简体   繁体   中英

Java - throws not working for a subtype of an exception that is handled

Take this as example:

public class TestClass {

    public static void test() throws SSLHandshakeException {
        throw new SSLHandshakeException("I'm a SSL Exception");
    }

    public static void main(String[] args) throws SSLHandshakeException {
        try {
            test ();        
        } catch (IOException ioe) {
            System.out.println("I`m handling IO exception");
        }       
    }
}

So, I have my test method in which I'm just throwing an SSLHandshakeException which is a subtype of IOException .

The output for this is "I`m handling IO exception".

Why does this happen? I expected that my method will throw the SSLHandshakeException . Is there a rule that catch is more important than throws ?

I just want to avoid using

try {
   test ();     
} catch (SSLHandshakeException se) { 
   throw se; 
} catch (IOException ioe) {
   System.out.println("I`m handling IO exception");
}   

Because I consider it less readable

Is there a rule that catch is more important than throws?

They are two completely different things. The throws keyword is part of the method signature and is saying 'This method can throw this exception, so every caller should handle that explicitly.'
Wether or not the method actually throws that exception is irrelevant here.

As for the catch statement. SSLHandshakeException is an IOException, and so it is caught as expected.

To get the behaviour you intent you can write:

    try {
        test ();
    } catch (SSLHandshakeException sslExc) {
        throw sslExc;
    } catch (IOException ioe) {
        System.out.println("I`m handling IO exception that is not an SSLHandshakeException");
    }

Edit: You say you find this less readable. But honestly this is just the best way. If it would behave the way you proposed than you would never be able to catch an SSLHandshakeException in a method that might also throw it? What if you want to catch it in certain conditions but throw it in others? It would just be too limiting and unintuitive.

An alternative is like so; but in my opinion this is even less readable:

    try {
        test ();
    } catch (IOException ioe) {
        if(ioe instanceof SSLHandshakeException)
            throw ioe;
        System.out.println("I`m handling IO exception that is not an SSLHandshakeException");
    }

That's probably because you printed your custom string instead of message of exception. Try this :

public static void main(String[] args) throws SSLHandshakeException {
    try {
        test ();        
    } catch (IOException ioe) {
        System.out.println("I`m handling IO exception");
        System.out.println(ioe.getMessage());

    }       
}

SSLHandshakeException is a subclass of javax.net.ssl.SSLException wich is a subclass of java.io.IOException .

So this code :

public static void main(String[] args) throws SSLHandshakeException {
     try {
          test ();        
         } catch (IOException ioe) {
            System.out.println("I`m handling IO exception");
        }       
}

will catch and IOException, and thus print the message "I`m handling IO exception".

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