【问题标题】:Why is it said: "Checked exceptions are not forwarded in calling chain (propagated)"?为什么说:“检查的异常不在调用链中转发(传播)”?
【发布时间】:2020-12-20 17:49:40
【问题描述】:

对于未经检查的(运行时)异常,这是可以理解的。它们实际上是通过堆栈传播的。但是为什么说受检异常不是呢?是的,我们必须声明(抛出)或处理(try-catch),但为什么在这种情况下不称为“传播”?让我给你一个基本的例子:

public class Main {
    void m() throws IOException {
        throw new java.io.IOException("device error");//checked exception
    }
    void n() throws IOException {
        m();
    }
    void p(){
        try{
            n();
        }catch(Exception e){System.out.println("exception handled");}
    }
    
    public static void main(String args[]){
        new Main().p();
    }
}

在我看来,我只是做了一个“链接”,效果很好。那么为什么文档说“默认检查不传播”?

【问题讨论】:

  • 您能否为该声明链接一个来源
  • 是的,请问您是从哪里引用的?我不知道有人这么说。
  • @Zabuzard here,我怀疑。

标签: java exception chaining propagation checked-exceptions


【解决方案1】:

默认情况下检查不传播

我相信这个消息的来源是here

这是一个不寻常的术语。 我怀疑那句话的意思是你不能只写:

void m() {
    throw new IOException("device error");//checked exception
}
void n() {
    m();
}
void p(){
    try{
        n();
    }catch(Exception e){System.out.println("exception handled");}
}

因为异常没有从m()“传播”到n()p(),因为它是一个检查异常,所以这段代码甚至无法编译。

如果它是未经检查的异常,它将被此代码从m()“传播”到n()p()

如果你想要的话,你必须明确地传播异常:

void m() throws IOException { ... }
void n() throws IOException { m(); }

这种传播的替代方法是在方法内部处理它。关键是,你必须选择如何处理它。

【讨论】:

    【解决方案2】:

    在运行时检查和未检查异常的行为实际上没有任何区别。

    检查的异常只是所有异常的一个子集,编译器决定查看它们并查看它们是显式声明为抛出还是捕获。如果不是,那就是错误。

    如果你能以某种方式hack the compiler to skip this check,它的行为就像运行时一样。

    鉴于运行时语义是相同的,说一个被传播而另一个不被传播是没有意义的。

    【讨论】:

    • 我完全同意你的看法。我认为他们可以更好地制定这条规则,因为它在技术上是错误的。我认为安迪说得很好,为什么这么说。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 2010-11-05
    相关资源
    最近更新 更多