如果我写
private void check(){
if(true)
return;
String a = "test";
}
以上代码正常,但如果我写
private void check(){
return;
String a = "test";
}
Android Studio中的编译器/ gradle并不会让它通过,即使它是相同的,并且它表示示例2中返回后的代码无法访问。
我对此没有任何问题,但我很想知道为什么?
答案 0 :(得分:1)
javac
编译器做了很少的优化,所以它根本没有“看到”if(true)
始终是true
(但你应该收到警告);但C1 / C2 JIT编译器将 - 所以代码只是return
,没有if语句。
答案 1 :(得分:1)
这可以通过Java语言规范的Unreachable Statements部分来解释。
有很多规则,有一个有趣的特例。这是一个编译时错误:
while (false) {
// this code is unreachable
String something = "";
}
虽然不是这样:
if (false) {
// this code is considered as reachable
String something = "";
}
给出的原因是允许某种条件编译,例如:
static final boolean DEBUG = false;
...
if (DEBUG) { x=3; }
所以在你的情况下:
private void check(){
if(true)
return;
// NO compilation error
// this is conditionnal code
// and may be omitted by the compiler
String a = "test";
}
由于特殊if
处理,不是错误,因此不接受使用while
:
private void check(){
while(true)
return;
// "Unreachable statement" compilation error
String a = "test";
}
这也是错误的:
private void check(){
if(true)
return;
else
return;
// "Unreachable statement" compilation error
String a = "test";
}
答案 2 :(得分:0)
当它尝试编译时,它会构建一个抽象语法树。在第一种情况下,'true'是一个匿名变量,因此将添加两个分支,即使只有一个分支是可能的。在第二种情况下,只有一个可能的分支要创建,它永远不会到达终点。
答案 3 :(得分:0)
区别在于这些需要两种不同的分析来确定行为。第一个例子需要语义分析,而后者需要语法分析。编译器是语法方面的专家;这就是他们要做的事情。但是,他们经常在语义上挣扎。执行静态语义分析需要编译器编写者花费更多精力,并且通常很难得到正确的。