简体   繁体   中英

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:

throw new Exception();

But now it seems that I have to handle some exception from JavaMail - MessagingException . It comes from the method Store.close (inherited from Service class).

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? 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 ). 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 .

Does it make sense from an API design viewpoint? 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.

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

The requirement to declare checked exceptions allows a Java compiler to ensure that code for handling such error conditions has been included. 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. The Java programming language thus encourages a programming style where rare and otherwise truly exceptional conditions are documented in this way.

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. It is forbiden, you can't add or use a super class of an exception in the subclass throws declaration

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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