static int retIntExc() throws Exception{
int result = 1;
try {
result = 2;
throw new IOException("Exception rised.");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
result = 3;
} finally {
return result;
}
}
我的一位朋友是.NET开发人员,目前正在迁移到Java,他问我关于这个来源的以下问题。从理论上讲,这必须throw IOException("Exception rised.")
,整个方法retIntExc()
必须throws Exception
。但没有任何反应,该方法返回2.
我没有测试他的例子,但我认为这不是预期的行为。
编辑:感谢所有答案。你们有些人忽略了这个方法被称为retIntExc
的事实,这意味着这只是一些测试/实验的例子,显示了投掷/捕捉机制的问题。我不需要'修复',我需要解释为什么会这样。
答案 0 :(得分:16)
这就是你无法从C#中的finally块返回的原因:)
这绝对是Java语言规范中规定的行为。它在section 14.20.2中指定。
如果finally块因为S而突然完成,那么try语句突然完成,原因是S(并且丢弃并抛弃了值V的抛出)。
回归是突然完成的一个例子;如果finally
块引发异常,也突然完成,丢失原始异常。
上面的引用来自这套嵌套的项目符号,省略了不适用的选项:
- 如果由于抛出值V而突然完成try块的执行,则可以选择:
- 如果V的运行时类型不能分配给try语句的任何catch子句的参数,则执行finally块。然后有一个选择:
- 如果finally块因为S而突然完成,那么try语句突然完成原因S(并且丢弃并抛弃值V的抛出)。
答案 1 :(得分:3)
它将返回2
,因为
finally
始终执行
答案 2 :(得分:2)
无论抛出什么异常,finally
块都会执行。在您声明的catch
块捕获异常后,它不会立即执行。它在try
块之后执行,并且如果有任何则捕获异常。如果您的方法抛出异常,除非您在方法中吞下它并返回result
,否则它不会返回任何内容。但你不能兼得。
此外,除非您的方法有任何其他代码,否则永远不会遇到ArrayIndexOutOfBoundsException
。
答案 3 :(得分:2)
这是因为您在异常传递之前发出了一个return语句,因此返回了一个有效值。你不能同时返回一个值并抛出异常。
删除返回周围的finally块将提供您想要的行为。
答案 4 :(得分:0)
IOException 类不是 ArrayIndexOutOfBoundsException 类的子类,因此将永远不会执行catch部分。
如果更改为此,则返回3.
static int retIntExc() throws Exception{
int result = 1;
try {
result = 2;
throw new ArrayIndexOutOfBoundsException ("Exception rised.");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
result = 3;
} finally {
return result;
}
}
答案 5 :(得分:0)
我不明白为什么这不会是预期的行为。到此代码块结束时,结果等于2.
static int retIntExc() throws Exception{
int result = 1;
try {
result = 2;
然后抛出一个异常,但是你的catch块会捕获不同类型的异常,因此不执行任何操作。
throw new IOException("Exception rised.");
} catch (ArrayIndexOutOfBoundsException e) {
...
}
保证finally块被执行,所以最后一步是返回2.
这次成功的回报否决了冒泡异常。如果您希望异常继续冒泡,那么您不能返回finally块。
答案 6 :(得分:0)
通过将return
放在finally方法中,您可以覆盖抛出的异常,而是返回结果。你的代码应该是这样的:
static int retIntExc() throws Exception{
int result = 1;
try {
result = 2;
throw new IOException("Exception rised.");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
result = 3;
} finally {
// do something
}
// it gets here only when exception is not thrown
return result;
}