フォローアップ コードで、以前は知らなかった動作に遭遇しました。
最初のケースを考えてみましょう:
public static void main(String[] args) {
final String str = null;
System.out.println(str.length()); // Compiler Warning: NullPointerAccess
}
予想通り、コンパイラはnullstr
であることに関する次の警告を表示します- Null ポインター アクセス:変数 str は、この場所でのみ null にすることができます。
ここで、その変数を移動すると、nullに初期化されたstatic final フィールド:
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
後で結果をもたらします。
ただし、コンパイラは最初のケースでこれを正常に警告しますが、2番目のケースでこれを識別できないのはなぜですか。この行動の変化はなぜですか?static
フィールドをinstance
フィールドに変更し、のインスタンスを使用してアクセスする場合、動作は同じですDemo
。
この動作は JLS で指定されている可能性があると考えたので、Definite Assignmentのトピックを調べましたが、この問題に関連するものは見つかりませんでした。行動の変化を説明できる人はいますか?可能であれば、JLSへのリンクを備えた強みを探していますか?
それとは別に、コンパイラが最初に警告のみを表示するのはなぜですか。上記と同じ理由で、フィールドを変更できないため、メソッド呼び出しは実行時にNPEを確実にスローしますか? コンパイラエラーが表示されなかったのはなぜですか? のランタイム結果str.length()
がNPE
.
以前のことを逃して申し訳ありません:
OpenJDK 7を搭載したUbuntu 12.04でEclipse Junoを使用しています。