我在后续代码中遇到了一种我之前不知道的行为。
考虑第一种情况:
public static void main(String[] args) {
final String str = null;
System.out.println(str.length()); // Compiler Warning: NullPointerAccess
}
str
正如预期的那样,编译器向我显示以下关于为空的警告-空指针访问:变量 str 在此位置只能为空。
现在,当我移动该变量时,静态 final 字段初始化为null:
class Demo {
static final String str = null;
public static void main(String[] args) {
System.out.println(str.length()); // No Compiler Warning
}
}
现在,编译器没有显示任何警告。AFAIK,编译器应该知道,str
最终,在代码的任何时候都不会改变它的值。鉴于它是null
,肯定会在NullPointerException
以后产生,它确实如此。
虽然,编译器在第一种情况下成功地警告了我,但为什么它在第二种情况下无法识别。为什么会发生这种行为变化?行为是相同的,如果我将static
字段更改为instance
字段,并使用Demo
.
我认为这种行为可能已在 JLS 中指定,因此我浏览了主题Definite Assignment,但没有找到与此问题相关的任何内容。谁能解释行为的变化?如果可能的话,我正在寻找一些与 JLS 的链接的强项?
除此之外,为什么编译器首先只向我显示警告,因为我认为出于与上述相同的原因,方法调用肯定会在运行时抛出NPE,因为该字段无法更改?为什么它不向我显示编译器错误?我是否对编译器期望过高,因为它似乎很明显,运行时结果str.length()
不能是什么NPE
?
很抱歉之前错过了:
我在Ubuntu 12.04上使用Eclipse Juno和OpenJDK 7。