Java中的编译器如何决定无法访问的代码?

时间:2014-11-29 19:25:32

标签: java dead-code

编译器如何决定无法访问的代码?

考虑这些

public class Test15 {

    public static final boolean verdict = false;
    public static final int verdictInt = 2;

    public static void main(String[] args) throws IOException {

        // case1
        if (verdict) {
            System.out.println(1);
        } else {
            System.out.println(2);
        }// compiles

        //case 2
        int val = 5;
        switch (val) {
         case verdictInt:System.out.println(3);
                        break;
        }// compiles

        //case 3
        while (false) {

        }// does not compile

        //case 4
        return 6;
        return 7;
        //does not compile

    }
}

因此当编译器决定代码无法访问时。因为(缺少更好的术语)硬代码(如案例4)。因为根据我的知识,判决,verdictInt也有资格作为编译时常量和据说也是。 根据我的阅读,能够使用常量verdictInt作为switch case标签表明它是一个编译时常量。

如果我的推理存在任何基本缺陷,请告诉我。

2 个答案:

答案 0 :(得分:3)

关于无法访问的代码的Java Language Specification部分是一个很好但很长的阅读。我会将它浓缩成可以翻译你的问题的内容。

案例1:

verdict可以看作是一个标志变量;它可能会也可能不会用于调试目的。如果是,那么破坏编译将导致重大的设计目标错过。规范明确地将其称为:

  

这种不同的处理[与if相对而不是while]的理由是允许程序员   定义“标志变量”,例如:

static final boolean DEBUG = false;
     

然后编写如下代码:

if (DEBUG) { x=3; }
     

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

案例2:

您的switch声明可以通过JLS的规则正常完成:

  

如果至少满足下列条件之一,则switch语句可以正常完成:

     
      
  • switch块为空或仅包含开关标签。
  •   
  • switch块中的最后一个语句可以正常完成。
  •   
  • 在最后一个switch阻止声明组之后至少有一个switch标签。
  •   
  • switch块不包含default标签。
  •   
  • 有一个可访问的break语句退出switch语句。
  •   

您的switch没有default标签,因此您的交换机可以正常完成。它刚刚脱离开关。

案例3:

这显然是编译。案例1引起了人们的注意,但是在这里它已经阐明了,强调我的:

  

while语句可以正常完成iff至少其中一个   以下是真的:

     
      
  • while语句是可以访问的,条件表达式不是值为true的常量表达式(第15.28节)。

  •   
  • 有一个可访问的break语句退出while语句。

  •   
     

如果while语句可达且条件表达式不是常量表达式,则可以访问包含的语句   其值为false

条件表达式为false,因此根据定义,您无法访问包含的语句。

案例4:

return是一个特例;它completes abruptly。一旦语句突然完成,之后的任何语句都无法按定义到达。

答案 1 :(得分:0)

在第3种情况下,它知道它不是循环,因为该值始终为false。 在案例4中,它知道之前存在无限循环,因此它表示无法访问的代码。 但是返回7;因为有回报6也无法到达;在它之前总是运行。

就像在做:

printf("Hello");
return 0;
printf("Never reached code");

我不知道这是否会导致无法接收的错误:

final int i = 5; float x = 0;
while(i<8) {
    x += 0.001f; 
    // Do Nothing
}
printf("Hello World");