Я столкнулся с поведением, о котором я раньше не знал, в последующем коде.
Рассмотрим случай 1 st:
public static void main(String[] args) {
final String str = null;
System.out.println(str.length()); // Compiler Warning: NullPointerAccess
}
Как и ожидалось, компилятор показывает, что следующее предупреждение на str
имеет значение null - Null-указатель: переменная str может быть только нулевой в этом месте.
Теперь, когда я переместил эту переменную, статическое конечное поле, инициализированное нулем:
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, поэтому я просмотрел раздел "Определенное задание", но не нашел ничего, связанного с этой проблемой. Может ли кто-нибудь объяснить изменения в поведении? Я ищу какую-то сильную точку с некоторой ссылкой на JLS, если это возможно?
Кроме того, почему компилятор показывает мне только предупреждение в первую очередь, так как я думаю по той же причине, о которой я говорил выше, вызов метода определенно бросает NPE во время выполнения, так как поле не может быть изменено? Почему это не показало мне ошибку компилятора? Я ожидаю слишком многого от компилятора, поскольку, как представляется, совершенно очевидно, что результат выполнения str.length()
не может быть чем-то вроде NPE
?
Простите, что раньше не было:
Я использую Eclipse Juno, на Ubuntu 12.04 с OpenJDK 7.