Java 在检测未初始化的局部变量时有多聪明?
How smart is Java when detecting an uninitialized local variable?
我知道 Java 强制您在使用每个局部变量之前对其进行初始化。但是,在某些情况下它会变得棘手。考虑一下:
public class TestClassOne {
public void methodOne() {
String s;
if(false)
System.err.println(s);
else
s = "Hi";
}
}
这个class将编译成功。但是,这个不会:
public class TestClassTwo {
public void methodTwo() {
String s;
if("hola".equals("chau"))
System.err.println(s);
else
s = "Hi";
}
}
为什么 Java 能够检测到 if 块永远不会在第一个 class 中输入,而在第二个中却不能?
编辑:
感谢您的回答。
我正在寻找的是确保程序可以编译的 if 条件的正式特征。
如果 if 条件是编译时布尔常量,那么是否可以安全地断定此代码将编译?起初我会想到 "no, in most cases you would get 'unreachable code' error" (除了 Jesper 指出的字面错误情况),但我已经尝试了以下给出的结果:
if(false) ... //compiles
if(0 == 1) ... //compiles
final boolean b = false;
if(b) ... //compiles
if (false)
是支持条件编译的特例.
有关无法访问的语句的详细说明,请参见Example 13.4.9-2 in the Java Language Specification and Paragraph 14.21。
Java 知道 if (false)
块的内容永远不会执行,所以它不会抱怨使用了未初始化的变量,但它不会抱怨 "unreachable code" 错误,因为特殊的条件编译情况。
对于像 equals()
这样的方法调用,编译器不会分析代码以查看在这种情况下总是 returns false
。
在 JVM 级别,编译器不会 "know" 任何有关字符串相等性的信息 - equals() 只是另一个 class 上的另一种方法。如果将 "equals" 替换为 "someMethod",那么很明显为什么编译器没有 "know" - 那些运行时对象不存在于编译器的 JVM 中,并且无法调用方法他们(也不能保证结果会保持不变!)
我知道 Java 强制您在使用每个局部变量之前对其进行初始化。但是,在某些情况下它会变得棘手。考虑一下:
public class TestClassOne {
public void methodOne() {
String s;
if(false)
System.err.println(s);
else
s = "Hi";
}
}
这个class将编译成功。但是,这个不会:
public class TestClassTwo {
public void methodTwo() {
String s;
if("hola".equals("chau"))
System.err.println(s);
else
s = "Hi";
}
}
为什么 Java 能够检测到 if 块永远不会在第一个 class 中输入,而在第二个中却不能?
编辑:
感谢您的回答。
我正在寻找的是确保程序可以编译的 if 条件的正式特征。
如果 if 条件是编译时布尔常量,那么是否可以安全地断定此代码将编译?起初我会想到 "no, in most cases you would get 'unreachable code' error" (除了 Jesper 指出的字面错误情况),但我已经尝试了以下给出的结果:
if(false) ... //compiles
if(0 == 1) ... //compiles
final boolean b = false;
if(b) ... //compiles
if (false)
是支持条件编译的特例.
有关无法访问的语句的详细说明,请参见Example 13.4.9-2 in the Java Language Specification and Paragraph 14.21。
Java 知道 if (false)
块的内容永远不会执行,所以它不会抱怨使用了未初始化的变量,但它不会抱怨 "unreachable code" 错误,因为特殊的条件编译情况。
对于像 equals()
这样的方法调用,编译器不会分析代码以查看在这种情况下总是 returns false
。
在 JVM 级别,编译器不会 "know" 任何有关字符串相等性的信息 - equals() 只是另一个 class 上的另一种方法。如果将 "equals" 替换为 "someMethod",那么很明显为什么编译器没有 "know" - 那些运行时对象不存在于编译器的 JVM 中,并且无法调用方法他们(也不能保证结果会保持不变!)