64 java compiler-errors return try-catch try-catch-finally
这是一个采访问题:
public class Demo {
public static void main(String[] args) {
System.out.println(foo());
}
static String foo() {
try {
return "try ...";
} catch (Exception e) {
return "catch ...";
} finally {
return "finally ..."; //got as result
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么没有编译时错误.当我在finally块中有return语句时,它必然会从而finally不是try和catch块返回.我尝试使用-Xlint选项编译此代码,它会发出警告.
warning: [finally] finally clause cannot complete normally
Run Code Online (Sandbox Code Playgroud)
Hoo*_*pje 77
它不会产生编译错误,因为Java语言规范允许它.但是,它会发出警告消息,因为return在finally块中包含一个语句通常是个坏主意.
您的示例中发生的情况如下.块中的return语句try被执行.但是,finally必须始终执行该块,以便在catch块完成后执行该块.在return那里发生的语句会覆盖前一个return语句的结果,因此该方法返回第二个结果.
类似地,finally块通常不应该抛出异常.这就是为什么警告说finally块应该正常完成,也就是说,没有return或抛出异常.
Dra*_*vic 39
这在Java语言规范中描述:
突然完成一个
finally条款可以破坏由return声明发起的控制权转移.
如果
try块的执行正常完成,则finally执行块,然后有一个选择:
- 如果
finally块正常完成,则try语句正常完成.- 如果
finally块因原因S突然完成,则try语句突然完成,原因是S.如果
try由于任何其他原因导致finally块的执行突然完成,则执行该块,然后有一个选择:
- 如果
finally块正常完成,则try语句突然完成,原因是R.- 如果
finally块因原因S而突然完成,则try语句突然完成,原因为S(并且原因R被丢弃).
Aak*_*ash 10
没有编译时错误,因为只有1和1的return语句实际上会将控件返回给调用代码.
正如@Hoopje所解释的那样,return在他们内部try或catch将首先执行,他们各自的返回声明也将执行.但就在将控制权返回给调用代码之前,它将执行该finally块.现在,这block也是return一些东西,所以这个回归会覆盖前一个回归.
很棒的问题..根据我的知识,如果你已经将finally块添加到你的代码中,那么try和catch块的return语句将被转移到finally.这是它的工作方式.
所以在这种情况下,所有代码行都在执行,您可以尝试调试.我在代码下面尝试了所有三个块.
public class Main {
public static void main(String[] args) {
System.out.println(foo());
}
static String foo() {
try {
throw new Exception();
} catch (Exception e) {
return "catch ...";
} finally {
return "finally ..."; //got as result
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以从下面的链接中获取想法. 多次返回:哪一个设置最终返回值?
它与此基本相同:
public boolean someMethod(){
if(1 == 1){
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
它不会给出编译错误,但它会发出警告.只有在没有执行返回语句的情况下,编译器才会给出错误.
您的代码工作正常,因为在try,catch和finally块中只有一个return语句.如果您尝试在try,catch或finally块之一中写入两个返回语句,表示存在无法返回的返回语句,则会发生编译错误.
(简短答案- 阅读答案的粗体和斜体部分)
按照Java 8文档的执行流程。它为您提供详细信息。您可以根据以下内容推断return语句的执行。
通过首先执行try块来执行带有finally块的try语句。
然后有一个选择:
•如果try块的执行正常完成,则执行finally块,然后可以选择:
–如果finally块正常完成,则try语句正常完成。
–如果由于原因S突然完成了finally块,则由于原因S导致try语句突然完成。
•如果由于抛出值V而导致try块的执行突然完成,则可以选择:
–如果V的运行时类型与try语句的任何catch子句的可捕获异常类的赋值兼容,则选择第一个(最左侧)的此类catch子句。将值V分配给所选catch子句的参数,并执行该catch子句的Block。
然后有一个选择:
›如果catch块正常完成,则执行finally块。然后有一个选择:
»如果finally块正常完成,则try语句正常完成。
»如果finally块由于某种原因突然完成,则try语句由于相同的原因突然完成。
› 如果catch块由于原因R突然完成,则执行finally块。然后有一个选择:
»如果finally块正常完成,则try语句由于原因R突然完成。
» 如果final块由于原因S突然完成,则try语句由于原因S突然完成(并且原因R被丢弃)。
–如果V的运行时类型与try语句的任何catch子句的可捕获异常类的赋值不兼容,则将执行finally块。
然后有一个选择:
›如果finally块正常完成,则try语句由于抛出值V而突然完成。
›如果finally块由于原因S突然完成,则try语句由于原因S突然完成(并且丢弃了值V,并且将其抛弃了)。
•如果由于任何其他原因R导致try块的执行突然完成,则执行finally块,然后可以选择:
–如果finally块正常完成,则try语句由于原因R突然完成。
–如果final块由于原因S突然完成,则try语句由于原因S突然完成(并且原因R被丢弃)。
该链接中的解释很清楚-javaDoc
| 归档时间: |
|
| 查看次数: |
3616 次 |
| 最近记录: |