无法访问的代码编译器错误

2022-09-01 19:06:09

下面的代码给出了编译器错误unreachable statement

public static void main(String[] args) {
    return;
    System.out.println("unreachable");
}

有时出于测试目的,想要防止调用某个方法,因此快速执行此操作(而不是在使用方法的所有位置注释掉它)是立即从该方法返回,以便该方法不执行任何操作。然后我总是这样做来获得编译器错误是这样的

public static void main(String[] args) {
    if (true) {
        return;
    }
    System.out.println("unreachable");
}

我只是好奇,为什么它是编译器错误??它会以某种方式破坏Java字节码,是为了保护程序员还是别的什么?

另外(这对我来说更有趣),如果将java编译为字节码可以进行任何优化(或者即使它没有),那么为什么它不会检测到第二个示例中公然无法访问的代码?编译器伪代码对于检查语句是否不可访问是什么?


答案 1

无法访问的代码是没有意义的,因此编译时错误很有帮助。在第二个示例中不会检测到它的原因是,正如您所期望的那样,用于测试/调试目的。规范中对此进行了解释:

if (false) { x=3; }

不会导致编译时错误。优化编译器可能会意识到语句 x=3;将永远不会被执行,并且可能会选择从生成的类文件中省略该语句的代码,但语句 x=3;不被视为此处指定的技术意义上的“无法访问”。

这种不同处理的基本原理是允许程序员定义“标志变量”,例如:

static final boolean DEBUG = false;

然后编写代码,例如:

if (DEBUG) { x=3; }

这个想法是,应该可以将DEBUG的值从false更改为true或从true更改为false,然后正确编译代码,而无需对程序文本进行其他更改。

参考资料: http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.21


答案 2

这是因为编译器编写者认为控件中的人是愚蠢的,并且可能并不意味着添加永远不会执行的代码 - 因此,通过抛出错误,它试图阻止您无意中创建无法执行的代码路径 - 而不是迫使您对此做出决定(即使, 正如你已经证明的那样,你仍然可以解决它)。


推荐