Java catch块内抛出异常-是否再次捕获?
这可能看起来像是一个编程101问题,我本以为我知道答案,但现在发现自己需要再次检查。在下面的这段代码中,第一个catch块中抛出的异常是否会被下面的常规异常catch块捕获Java catch块内抛出异常-是否再次捕获?,java,exception,Java,Exception,这可能看起来像是一个编程101问题,我本以为我知道答案,但现在发现自己需要再次检查。在下面的这段代码中,第一个catch块中抛出的异常是否会被下面的常规异常catch块捕获 try { // Do something } catch(IOException e) { throw new ApplicationException("Problem connecting to server"); } catch(Exception e) { // Will the Application
try {
// Do something
} catch(IOException e) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}
我一直以为答案是否定的,但现在我有一些奇怪的行为,可能是由这引起的。大多数语言的答案可能都是一样的,但我用的是Java。不,因为新的
throw
不直接在try
块中。不——正如Chris Jester Young所说,它将被抛出到层次结构中的下一个try catch中。如上所述……我想补充一点,如果你看不清发生了什么,如果你不能在调试器中重现问题,你可以在重新抛出新异常之前添加一个跟踪(更糟糕的是,使用好的旧System.out.println,使用像log4j这样的好日志系统)。不,这很容易检查
public class Catch {
public static void main(String[] args) {
try {
throw new java.io.IOException();
} catch (java.io.IOException exc) {
System.err.println("In catch IOException: "+exc.getClass());
throw new RuntimeException();
} catch (Exception exc) {
System.err.println("In catch Exception: "+exc.getClass());
} finally {
System.err.println("In finally");
}
}
}
应打印:
In catch IOException: class java.io.IOException
In finally
Exception in thread "main" java.lang.RuntimeException
at Catch.main(Catch.java:8)
在catch IOException中:类java.io.IOException
终于
线程“main”java.lang.RuntimeException中的异常
at Catch.main(Catch.java:8)
从技术上讲,这可能是一个编译器错误、依赖于实现、未指定的行为或其他原因。然而,JLS已经非常明确,编译器对于这类简单的事情来说已经足够好了(泛型案例可能是另一回事)
还要注意的是,如果您交换两个catch块,它将无法编译。第二个陷阱是完全不可能实现的
注意,即使执行了catch块,finally块也始终运行(除了愚蠢的情况,例如无限循环、通过tools接口连接、终止线程、重写字节码等)。第二个catch块不会捕获finally块。仅当在try块中时,才会捕获每个异常。不过,您可以尝试嵌套(一般来说,这不是一个好主意):
不,因为catch都引用同一个try块,所以从catch块内进行的抛出将被一个封闭的try块捕获(可能在调用此块的方法中)Java语言规范在第14.19.1节中说: 如果try块的执行由于抛出值V而突然完成,则有一个选择:
- 如果V的运行时类型可分配给try语句的任何catch子句的参数,则选择第一个(最左边的)catch子句。值V被分配给所选catch子句的参数,并执行该catch子句的块。如果该块正常完成,则try语句正常完成如果该块由于任何原因突然完成,则try语句也会因为同样的原因突然完成。
需要知道的一件相关且令人困惑的事情是,在try-[catch]-finally结构中,finally块可能会抛出异常,如果是这样,try或catch块抛出的任何异常都将丢失。第一次看到它时可能会感到困惑。如果要从catch块抛出异常,必须通知方法/类等,它需要抛出所述异常。像这样:
public void doStuff() throws MyException {
try {
//Stuff
} catch(StuffException e) {
throw new MyException();
}
}
现在,编译器不会对您大喊大叫:)旧帖子,但“e”变量必须是唯一的:
try {
// Do something
} catch(IOException ioE) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}
也许您可以描述一下“奇怪的行为”?您确定ApplicationException没有被抛出到其他地方并传播到这个块吗?我在Eclipse IDE中注意到了这一点。这是轮胎迫使我把“抛出新的异常”在一个尝试块,但我不知道为什么。我过去做过,但没有这样做。我不明白为什么需要try块。谷歌上的许多例子表明,人们不需要try块。这是因为我在if语句中插入了一条语句吗?避免
最后出现的最明显方法当然是调用系统。退出:-P@ChrisJester Young代表(;)代码>较短,包含在语言中,不会带来太多副作用,对我来说,更明显。System.exit
对CPU更友好!:-O但是是的,好的,很明显这是一个主观标准。还有,我不知道你是一个密码高尔夫球手这应该是评论,而不是回答。它没有提供任何解决实际问题的方法—它只是对OPs问题的批评。只是想补充一点,因为Java 7可以避免在资源中使用try
。然后,如果try
和finally
都抛出,finally
被抑制,但也被添加到try
的异常中。如果catch
也抛出,你就没有运气了,除非你自己通过'addsupprested'并添加try
exception来处理,那么你就拥有了这三个异常。假设代码是这样的,那么就试试{}catch(exception e){System.err.println(“in catch exception:+e.getClass());}catch(IOException e){System.err.println(在catch IOException中:“+e.getClass());}try块中的代码会生成IO异常,它会进入即时通用异常块还是会飞到IOException catch块?@user3705478为了避免这种错误情况,代码不会编译。通常,在同一try块中捕获子类的超类之后,不允许子类捕获。t汉克斯。所以我会得到一个编译时错误,对吗?我回家后会测试它。这取决于@user3705478,如果从catch
块抛出RuntimeException
,就不会有编译错误了。@AndrewDunn我不认为这是user3705478的问题所在,而是,如果一个父级
try {
// Do something
} catch(IOException ioE) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}