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

时间:2012-02-14 11:53:53

标签: java compiler-construction

以下代码给出了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到字节码进行任何类型的优化(或者即使它没有)那么为什么它不会在第二个例子中检测到明显无法访问的代码呢?编译器伪代码用于检查语句是否无法访问?

7 个答案:

答案 0 :(得分:22)

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

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

答案 1 :(得分:7)

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

答案 2 :(得分:2)

此错误主要是为了防止程序员错误(交换2行或更多行)。在第二个片段中,您清楚地表明您不关心system.out.println()。

答案 3 :(得分:2)

  

它会以某种方式破坏Java字节码,它是为了保护程序员还是其他东西?

就Java / JVM而言,这不是必需的。编译错误的唯一目的是避免程序员的愚蠢错误。请考虑以下JavaScript代码:

function f() {
    return 
        {
            answer: 42
        }
}

此函数返回undefined,因为JavaScript引擎在行尾添加分号并忽略死代码(正如它所认为的那样)。 Java编译器更聪明,当它发现你正在做一些清楚而明显错误的事情时,它不会让你这样做。你本来没有办法打算使用死码。这在某种程度上符合Java作为安全语言的前提。

答案 4 :(得分:0)

在第一种情况下,您在任何语句之前返回,因为它编译器永远不会执行该代码。

在第二个代码中,我将声明置于返回及其工作之上:)

这背后的原因是,如果你返回某个时间,那么代码永远不会执行,因为你已经返回了函数数据,因此它显示为无法访问的代码。

public static void main(String [] args){

return;
System.out.println("unreachable");

}

/////////////////////////////////

public static void main(String [] args){

System.out.println("unreachable"); // Put the statement before return
return;

}

答案 5 :(得分:0)

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

表示:

14.21。无法访问的语句

如果语句因无法访问而无法执行,则为编译时错误。

答案 6 :(得分:-1)

这是因为即使在那里也浪费资源。此外,编译器设计人员不想假设他们可以删除的内容,而是强迫您删除使其无法访问的代码或无法访问的代码本身。他们不知道那里应该是什么。优化之间存在差异,它们将代码调整为在编译为机器代码时更高效,并且公然只删除“您不需要的代码”。