使用JavaSE6(和以前的版本)更精确地重新抛出异常
鉴于以下计划:使用JavaSE6(和以前的版本)更精确地重新抛出异常,java,exception,Java,Exception,鉴于以下计划: class FirstException extends Exception {} class SecondException extends Exception {} class RethrowException { public void rethrowMethod() throws FirstException, SecondException { boolean flag = true; try {
class FirstException extends Exception {}
class SecondException extends Exception {}
class RethrowException {
public void rethrowMethod() throws FirstException, SecondException {
boolean flag = true;
try {
if(flag)
throw new FirstException();
else
throw new SecondException();
}
catch(Exception ex) {
throw ex; // does not compile "Unhandled exception type Exception"
}
}
}
这个错误只发生在JavaSE6(或之前的版本)中,因为首先,当我们构建“catch”块(catch(Exception ex))时,由ex指定的异常对象的类型为FirstException
(或SecondException)。但是,当重新抛出ex
时(throw ex
),Java编译器将执行以下3项任务:
FirstException
(或SecondException
)的实例ex
时,运行时系统不会释放和初始化新对象ex
。它将检查(查找)ex1的来源(上面的try块),从而知道ex是
FirstException或
SecondException`的实例
我上面的解释是否正确?在Java上的任何版本中,捕获异常并从
catch
块抛出它都不会创建新的异常实例
在Java6-中,捕获的异常的类型由catch
块声明为exception
,因此编译器认为这就是抛出的异常类型
在以后的版本中,异常类型被推断为仅限于可以从
try
块抛出的异常。我不知道这是您的解释的哪一部分,问题的哪一部分。我可以告诉您“为什么我可以在Java 7或更高版本上编译它,而不是Java 6或更低版本上编译它”的答案(如果确实如此)与运行时行为无关。这与编译器变得更加智能有关。这真的是在Java>6中编译的吗?对我来说,这似乎是一个糟糕的做法。编辑:是的,我看到这个示例来自Java文档。@NickL:是的,它是。编译器知道在我不明白,当我检查“ex”(使用instanceof)的类型时,我得到了“FirstException”。所以,“ex”有FirstException类型,为什么当我们重试时,运行时系统会抛出Exception类型,而它是FirstException?@Johninstanceof
是一个运行时的东西。错误是编译时的东西。编译器很愚蠢。它没有解释什么东西可能是什么,它只看它声明的东西。Java 7+稍微聪明一点er在这种情况下。你手边有JLS参考吗?我试图找到描述这种行为的地方,但还没有找到。@ErwinBolwidt文档(OP从中获得示例)描述了这种行为()。我认为是相关的JLS部分“我们说,如果根据§11.2.1和§11.2.2中的规则,语句或表达式的执行可能导致抛出E类异常,则语句或表达式可以抛出E类异常。“@SimonForsberg,他们在Java7中添加了整个多捕获语法,我相信,这意味着编译器必须检查try
块实际可能抛出的内容,并产生(或不产生)相应的错误。如果它看到try
只抛出IOException
,它甚至可以从同一个catch块中重新抛出Throwable
,并且推断的异常类型被缩小为IOException
,不管如何。在某种程度上,这就是它的行为方式。