【问题标题】:Throw Sub-Exception, catch as Super Exception and re-throw it but declare throws Sub-Exception抛出 Sub-Exception,捕获为 Super Exception 并重新抛出它,但声明 throws Sub-Exception
【发布时间】:2019-01-21 07:36:03
【问题描述】:

Java 文档在处理类型转换、覆盖方法的返回类型以及抛出和捕获异常时清楚地解释了对象的一致性。但是现在我对异常有点困惑,这段代码背后隐藏的概念是什么..

void getNames() throws SQLClientInfoException { /*throws Subclass object to caller*/
    try{
        // throwing Subclass object to catch block but up-casting to Exception
        throw new SQLClientInfoException(); 
    } catch (Exception e) {
        throw e; /* re-throwing throwing as Exception 
    }
}

【问题讨论】:

    标签: java exception exception-handling


    【解决方案1】:

    它是 Java SE 7 中引入的编程语言的一个特性 - 在异常中使用更精确的重新抛出。

    与早期版本的 Java 相比,Java SE 7 编译器对重新抛出的异常执行更精确的分析。这样可以在方法声明的 throws 子句中指定更具体的异常类型。

    Java 7 之前:

    void aMethod() throws CustomDbException {
        try {
            // code that throws SQLException
        }
        catch(SQLException ex) {
            throw new CustomDbException();
        }
    }
    
    • 在 catch 块中重新抛出异常不需要表明 try 块中可能出现的实际异常。
    • 抛出的异常类型不能在不改变的情况下改变 方法签名。

    在 Java 7 或更高版本中:

    void aMethod() throws IOException {
        try {
            Files.copy(srcePath, trgtPath); // throws IOException
        }
        catch(Exception ex) {
            throw ex;
        }
    }
    

    以上代码在 Java 7 中是合法的。

    • 如果在 try 子句中抛出了某种类型的异常,并且未在 catch 子句中分配异常变量,编译器将复制可从 try 块中抛出的已检查异常类型。 (如果不重新分配异常变量,就好像从 try 块中抛出所有可能的异常)。
    • 编译器知道唯一可能的异常类型是IOException(因为这是Files.copy() 可以抛出的)。

    另外,请参阅 Oracle 网站上的这篇文章:Rethrowing Exceptions with More Inclusive Type Checking

    【讨论】:

    • 非常感谢@prasad 的链接。
    【解决方案2】:

    因为SQLClientInfoException是“java.lang.Exception”的子类,所以在抛出SQLClientInfoException时会被catch块捕获

    catch 块中的“e”变量指的是 SQLClientInfoException。

    【讨论】:

    • 你是对的@mfe,但在这种情况下,我从 catch 中抛出异常并声明抛出异常的子类
    猜你喜欢
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多