编译器如何决定无法访问的代码?
考虑这些
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标签表明它是一个编译时常量。
如果我的推理存在任何基本缺陷,请告诉我。
答案 0 :(得分:3)
关于无法访问的代码的Java Language Specification部分是一个很好但很长的阅读。我会将它浓缩成可以翻译你的问题的内容。
verdict
可以看作是一个标志变量;它可能会也可能不会用于调试目的。如果是,那么破坏编译将导致重大的设计目标错过。规范明确地将其称为:
这种不同的处理[与
if
相对而不是while
]的理由是允许程序员 定义“标志变量”,例如:static final boolean DEBUG = false;
然后编写如下代码:
if (DEBUG) { x=3; }
这个想法是应该可以改变DEBUG的值 从false到true或从true到false然后编译代码 正确,没有对程序文本进行其他更改。
您的switch
声明可以通过JLS的规则正常完成:
如果至少满足下列条件之一,则
switch
语句可以正常完成:
switch
块为空或仅包含开关标签。switch
块中的最后一个语句可以正常完成。- 在最后一个
switch
阻止声明组之后至少有一个switch
标签。switch
块不包含default
标签。- 有一个可访问的
break
语句退出switch
语句。
您的switch
没有default
标签,因此您的交换机可以正常完成。它刚刚脱离开关。
这显然是不编译。案例1引起了人们的注意,但是在这里它已经阐明了,强调我的:
while
语句可以正常完成iff至少其中一个 以下是真的:
while
语句是可以访问的,条件表达式不是值为true
的常量表达式(第15.28节)。有一个可访问的
break
语句退出while
语句。如果
while
语句可达且条件表达式不是常量表达式,则可以访问包含的语句 其值为false
。
条件表达式为false
,因此根据定义,您无法访问包含的语句。
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");