请帮我理解下面的代码,
案例1:
finally{
return;
System.exit(1);
}
以上代码抛出编译时错误:
无法访问的代码
案例2:
finally{
System.exit(1);
return;
}
上面的代码不会抛出任何编译/运行时错误,但是当我运行程序时只退出。
我的问题是,为什么设计人员想在案例1中抛出编译时错误,而在案例2中则没有。实际上,当您调用System.exit(0)时,程序将终止,这意味着它下面的代码无法访问。
答案 0 :(得分:5)
return
是编译器知道的语言功能。编译器将System.exit(1)
视为静态方法调用,类似于System.out.println(...)
。编译器不知道调用此方法实际上做了什么。
答案 1 :(得分:1)
案例1:
finally{
return;
System.exit(1);
}
这是无法访问的,因为编译器可以看到您从该方法返回,因此不会再运行任何代码。
案例2:
finally{
System.exit(1);
return;
}
上面的代码不会抛出任何编译/运行时错误,但是当我运行时 程序刚刚退出
exit()
的文档回答了这个问题:
终止当前运行的Java虚拟机。争论 作为状态代码;按照惯例,非零状态代码 表示异常终止
并且exit()
投掷的唯一例外是SecurityException
答案 2 :(得分:1)
在案例1中,您使用语言构造来退出块,之后的任何代码都将永远不会运行,因此编译器错误。
在案例2中,您正在调用一个强制JVM退出而不执行任何代码的方法,因此没有编译器错误。
答案 3 :(得分:1)
对于编译器,System.out.println()和System.exit()之间没有区别 - 两者都只是方法。编译器不会分析它的内容。
答案 4 :(得分:1)
编译器不检查方法的作用。编译器设计者做出的简单设计决定是 - 在返回语句(在同一块中)无法访问之后的任何代码行。
无论您是拨打System.exit()
还是explodeMyPC()
(这可能实际上是Kaboom您的电脑)都无关紧要。
答案 5 :(得分:1)
在第一种情况下,在调用System.exit之前从块返回,这意味着永远无法访问System.exit。
这是编译器可以识别的错误。
编译器对System.exit的行为方式一无所知
根据特定的库调用添加流分析会很慢而且很脆弱。
这样的分析最好留给静态分析工具。
答案 6 :(得分:1)
这是运行时与编译时间的区别。在第一种情况下,Java编译器阻止成功编译,因为语句System.exit(1)
永远不会被执行(如下所示:如果执行return
语句,则无法执行任何其他语句由于这个原因,Java规范禁止使用这种代码,编译器只是禁止使用这种代码。编译器知道return
语言特性,它强制要求没有其他代码。但是,System.exit(1)
被视为方法调用,就像任何其他API方法一样。
在第二种情况下,编译器不会将System.exit()
视为处理return;
语句的方式,这就是语句的效果仅留给运行时的原因。当此代码在运行时执行时,System.exit(1);
行被命中并且VM退出,从而没有机会到达return
语句。但是,编译器认为这是完全合法的代码。