public class Demo02 {
public static void main(String[] args) {
test();
}
public static void test() {
int a = 3;
if (true) {
return;
}
//else return;
System.out.println(1);
}
}
如上代码,if的条件是true,这就代表这调用test方法时,return一定会执行,后面的打印语句看起来是无法执行到的,按照平常来讲,这种代码直接就会编译报错,但是实际上是没有报错,除非加上else return;才会出现报错,请问这是为什么呢?JVM在进行编译的时候是怎么编译这段代码的呢?java在编译if else的时候会检查if()中的条件么?
看起来编译器在编译时,只会进行语义检查,并不会对if的条件进行实际计算。
有返回值的方法的检查每一个分支是否有值返回,以及后续语句能否执行到。
没有返回值的方法更关注后续语句是否能够正常执行
(1)问题分析
从结果上来看,java的编译器并不会查看if语句的条件是否一定成立,其似乎只关心从结构上讲一定会有return后不应该再有待编译语句。如果只有if语句里面有return,那编译器可能认为还存在if条件不成立的情况,但如果else语句里面也有return,那编译器就知道if和else结构后一定已经return了,此时如果后面还有待编译语句的话,就会触发“error: unreachable statement”的编译错误。
(2)代码验证分析1
同样加入else语句,但是else结构里面不返回,程序是可以正常编译运行的
class Demo02 {
public static void main(String[] args) {
System.out.println("Program starts.");
test();
}
public static void test() {
int a = 3;
if (true) {
return;
}
else
{
}
System.out.println("Test ends.");
}
}
程序运行结果:
class Demo02 {
public static void main(String[] args) {
System.out.println("Program starts.");
test();
}
public static void test() {
int a = 3;
if (true) {
return;
}
else if(true)
{
return;
}
System.out.println("Test ends.");
}
}
程序运行结果:
毕竟只是编译,不是运行。因此它是没有检查if的条件肯定成立这件事的。但如果有else return,那么它能检查出分支条件都return的情况的
因为else 加上return,后面的system.out...的打印就一定不会执行,所以会出现JAVA:36:无法访问的语句。
加上else if,整个else if和if差不多,只不过是if条件不满足的时候,会接着看第二个if,在虚拟机看来,不会100%执行,所以elseif 里面return,不会影响运行
通过你运行的现象可以断定,这个版本的java在编译的时候没有判断if里面的具体逻辑。
你在if else 的两个分支都return了,通过语法树在编译阶段就能断定这个if else走完流程就结束了。后面的语句永远不会执行。
这和在return;后面直接写语句效果一样。编译阶段就会报语句不可达之类的错误。
当有了else return后,就能检查出分支条件都return的情况,所以会报错