简体   繁体   English

Java异常来自何处?

[英]Where do Java exceptions came from?

Until now, I thought that every Java exception has to be created somewhere by a constructor, as I can create on my own, custom exceptions: 到目前为止,我认为每个Java异常都必须由构造函数创建,因为我可以自己创建自定义异常:

throw new Exception();

But now it seems that I have to handle some exception from JavaMail - MessagingException . 但是现在看来,我必须处理JavaMail- MessagingException中的某些异常。 It comes from the method Store.close (inherited from Service class). 它来自Store.close方法(从Service类继承)。

I went there (I need to check when this exception is thrown so I know what can be wrong) and I see that this method calls two other methods - none of them throw an exception! 我去了那里(我需要检查何时引发该异常,以便知道什么地方可能出了错),并且我看到该方法调用了另外两个方法-它们都不抛出异常!

public synchronized void close() throws MessagingException {
    setConnected(false);
    notifyConnectionListeners(ConnectionEvent.CLOSED);
}

As far as I understand, this is checked Exception (neither Error nor RuntimeException), so how is it possible that it doesn't have to be declared in any of used by close method commands? 据我了解,这是检查的异常(Error和RuntimeException均未检查),那么怎么可能不必在close方法命令使用的任何方法中都声明它? It is also not created here, in this method. 在此方法中,也不会在此处创建它。

The exception being declared isn't about what that implementation can throw - it's about what that implementation or the implementation in subclasses can throw. 声明的异常实现可能引发的异常无关而是与该实现或子类 中的实现可能引发的异常有关。 Service is an abstract class - and so are the two direct subclasses implemented by JavaMail ( Transport and Store ). Service是一个抽象类-JavaMail实现的两个直接子类( TransportStore )也是如此。 Even if neither of those overrides close() , it's still entirely possible that the concrete implementation you use may override close() and its implementation may throw MessagingException . 即使这些覆盖都不覆盖close() ,您使用的具体实现也有可能覆盖close()并且实现也可能抛出MessagingException

Does it make sense from an API design viewpoint? 从API设计的角度来看有意义吗? I'd have to look more closely at JavaMail to be any kind of judge of that, and thankfully I haven't had to use JavaMail for a long time. 我必须更仔细地研究JavaMail才能做出任何判断,而且值得庆幸的是,我已经很长时间没有使用JavaMail了。

Does it makes sense from a language viewpoint ? 从语言的角度来看有意义吗? Absolutely. 绝对。 It's entirely reasonable to have an implementation which doesn't throw a particular checked exception, but anticipates that concrete subclasses may need to. 拥有一个不抛出特定检查异常的实现,但是期望具体的子类可能需要这样做是完全合理的。

The JLS about method declaration says 关于方法声明的JLS说

The requirement to declare checked exceptions allows a Java compiler to ensure that code for handling such error conditions has been included. 声明检查异常的要求使Java编译器可以确保已包含用于处理此类错误情况的代码。 Methods or constructors that fail to handle exceptional conditions thrown as checked exceptions in their bodies will normally cause compile-time errors if they lack proper exception types in their throws clauses. 如果方法或构造函数无法处理作为主体中的检查异常引发的异常条件,则如果它们在throws子句中缺少适当的异常类型,通常会导致编译时错误。 The Java programming language thus encourages a programming style where rare and otherwise truly exceptional conditions are documented in this way. 因此,Java编程语言鼓励采用这种编程方式,在这种方式下,以这种方式记录了罕见的条件,或者说是真正的例外情况。

Basicly, it your are sure that the code won't compile if the exception is not handle. 基本上,如果没有处理异常,则可以确保代码不会编译。 So even if it is not thrown in this implementation, it could be in a subclass. 因此,即使未在此实现中抛出它,它也可能在子类中。

Read the full page for more detailed informations. 阅读整页以获得更多详细信息。

public class Mother{
    public foo() throws Exception{
         system.out.println("I am mother");
    }
}

public class Daughter extends Mother{

    @Override
    public foo() throws Exception{
         throws new Exception("I am a teenager !!");
    }
}

Since this is permited 由于这是允许的

Mother m = new Daughter();

You loose the real type of the instance so luckily the compiler will scream if you do 您松开了实例的真实类型,所以幸运的是,如果您这样做,编译器会尖叫

m.foo(); //will not compile

Note that you can't have the methods from mother without any throws declaration if the overrided methods in a subclass need to throws something. 请注意,如果子类中被重写的方法需要throws某些东西,那么您就无法从母亲那里获得没有任何throws声明的方法。 It is forbiden, you can't add or use a super class of an exception in the subclass throws declaration 禁止,您不能在子类throws声明中添加或使用异常的超类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM