为什么Java仅在while循环的情况下识别无法访问的代码?
如果我有类似的代码
public static void main(String args[]){ int x = 0; while (false) { x=3; } //will not compile }
编译器会抱怨x=3
是无法访问的代码但是如果我有代码那么
public static void main(String args[]){ int x = 0; if (false) { x=3; } for( int i = 0; i< 0; i++) x = 3; }
然后它正确编译,虽然if statement
和for loop
的代码是不可达的。 为什么java工作流逻辑没有检测到这种冗余? 任何用例?
如Java语言规范中所述 ,此function保留用于“条件编译”。
JLS中描述的一个例子是你可能有一个常数
static final boolean DEBUG = false;
以及使用此常量的代码
if (DEBUG) { x=3; }
我们的想法是提供一种方法,可以轻松地将DEBUG
从true
更改为false
而无需对代码进行任何其他更改,如果上面的代码给出了编译错误,这是不可能的。
if条件的用例是调试。 规范明确允许AFAIK if
-statements(不是for循环)允许这样的代码:
class A { final boolean debug = false; void foo() { if (debug) { System.out.println("bar!"); } ... } }
您可以稍后(或通过运行时调试器)更改debug
的值以获取输出。
编辑正如克里斯蒂安在他的评论中指出的那样,可以在这里找到与规范相关的答案。
关于for循环,我认为它不像在while循环中使用false
常量那样容易检测。
关于if
,这是一个故意选择授权它,以便能够在编译时从字节代码中删除调试代码:
private static final boolean DEBUG = false; // or true ... if (DEBUG) { ... }
if(false){x = 3; }不会导致编译时错误。 优化编译器可以实现语句x = 3; 将永远不会执行,并可能选择从生成的类文件中省略该语句的代码,但语句x = 3; 在此处指定的技术意义上,不被视为“无法访问”。
这种不同处理的基本原理是允许程序员定义“标志变量”,例如:
static final boolean DEBUG = false; 然后编写如下代码:
if(DEBUG){x = 3; 这个想法是应该可以将DEBUG的值从false更改为true或从true更改为false,然后正确编译代码而不对程序文本进行其他更改。