关于#java#的问题:在java中,return后面跟着语句,编译时一定报错么?


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.");
    }
}

程序运行结果:

img


(3)代码验证分析2
将else语句换成else if(true)语句,程序同样可以正常编译运行

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.");
    }
}

程序运行结果:

img


(4)总结
测试结果表明,对java编译器来说,只要从结构上讲,不是所有分支都一定return,那么后面就可以继续加待编译语句。

毕竟只是编译,不是运行。因此它是没有检查if的条件肯定成立这件事的。但如果有else return,那么它能检查出分支条件都return的情况的

除非加上else return;才会出现报错,请问这是为什么呢?JVM在进行编译的时候是怎么编译这段代码的呢?java在编译if else的时候会检查if()中的条件么?

因为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的情况,所以会报错