Java - 抛出不适用于已处理异常的子类型

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

以此为例:

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");
        }       
    }
}

所以,我有我的测试方法,其中我只是抛出一个 SSLHandshakeException,它是 IOException.

的子类型

此输出为 "I`m handling IO exception"。

为什么会这样?我预计我的方法会抛出 SSLHandshakeExceptioncatchthrows 重要吗?

我只想避免使用

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

因为我认为它的可读性较差

这可能是因为您打印了自定义字符串而不是异常消息。试试这个:

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());

    }       
}

SSLHandshakeExceptionjavax.net.ssl.SSLException 的子类,javax.net.ssl.SSLExceptionjava.io.IOException.

的子类

所以这段代码:

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

将捕获和 IOException,从而打印消息 "I`m handling IO exception"。

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

它们是完全不同的两个东西。 throws 关键字是 方法签名 的一部分,表示 'This method can throw this exception, so every caller should handle that explicitly.'
该方法是否实际抛出该异常在这里无关紧要。

至于catch的说法。 SSLHandshakeException 是一个 IOException,因此它会按预期被捕获。

要获得您想要的行为,您可以这样写:

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

编辑:你说你觉得这不太可读。但老实说,这只是最好的方法。如果它按照您建议的方式运行,那么您将永远无法在也可能抛出它的方法中捕获 SSLHandshakeException 吗?如果你想在某些情况下抓住它但在其他情况下扔掉它怎么办?这会太局限和不直观。

另一种方法是这样;但在我看来,这更难读:

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