为什么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 statementfor loop的代码是不可达的。 为什么java工作流逻辑没有检测到这种冗余? 任何用例?

如Java语言规范中所述 ,此function保留用于“条件编译”。

JLS中描述的一个例子是你可能有一个常数

 static final boolean DEBUG = false; 

以及使用此常量的代码

 if (DEBUG) { x=3; } 

我们的想法是提供一种方法,可以轻松地将DEBUGtrue更改为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,然后正确编译代码而不对程序文本进行其他更改。