私は内部クラスの仕組みを勉強していますし、そのバイトコードの内部で、私は、スタックをトレースたとはgetClass()が呼び出された理由を理解できませんでしたか?
私が見つかりました。ラムダ関数の同様の質問を、それを理解することができませんでした。
私はそれがJDK 8の後にそれがrequiredNoNullという静的関数によって置き換えられています、ノーヌルチェックのために必要であることを理解しようとしました。
コード:
class Outer{
class Inner{
}
public static void main(String args[]){
Outer.Inner obj = new Outer().new Inner();
}
}
バイトコード:
public static void main(java.lang.String[]);
Code:
0: new #2 // class Outer$Inner
3: dup
4: new #3 // class Outer
7: dup
8: invokespecial #4 // Method "<init>":()V
11: dup
12: invokevirtual #5 // Method java/lang/Object.getClass:()Ljava/lang/Class;
15: pop
16: invokespecial #6 // Method Outer$Inner."<init>":(LOuter;)V
19: astore_1
私の知る限り理解し、ユージンの答え@絶対に正しいです。私は簡単な言葉で説明を追加することにしました。うまくいけば、それが誰かを助けます。
回答:への呼び出しObject.getClass
、必要に応じてNullPointerExceptionsがを生成するJDK8にコンパイラによって使用されたが。あなたの例では、このチェックは、不要であるnew Outer()
nullにすることはできませんが、コンパイラはそれを決定するために、スマート十分ではありませんでした。
JDKのそれ以降のバージョンでは、ヌルのチェックはして使用するように変更され、より読みやすいしObjects.requireNotNull
。コンパイラはまた、離れた冗長ヌルチェックを最適化するために、改善されました。
説明:
このようなコードを考えてみましょう:
class Outer{
class Inner{
}
public static void main(String args[]){
Outer.Inner obj = ((Outer) null).new Inner();
}
}
それが必要として、このコードは、NullPointerExceptionがスローされます。
問題は、NPEは、ビューのJavaの点からだけ論理的である、です。コンストラクタは、バイトコードレベルで存在していません。コンパイラは、多かれ少なかれ同等以下の疑似コードにバイトコードを生成します。
class Outer {
public static void main(String[] args) {
Outer tmp = (Outer) null;
Outer.Inner obj = new; //object created
tmp."<init>"(tmp);
}
}
class Outer$Inner {
//generated field
private final Outer outer;
//generated initializer
void "<init>"(Outer outer) {
this.outer = outer;
}
}
あなたが見ることができるように、コンストラクタはメソッドに置き換えられました。そしてこの方法は、それ自体で、例外がスローされません、したがって、ヌルのためにそれの引数をチェックしません。
そのため、コンパイラは生成するために、追加のnullチェックを追加する必要がありますNullPointerException
。Javaの8の前に、これを達成するために迅速かつ汚い方法は、呼び出しを発するようにしましたgetClass
。
Outer tmp = (Outer) null;
tmp.getClass(); //generates an NPE
どのように、これは、確かに、その理由であることを確認することができます。
- コンパイル
Outer
JDK 8を使用して、上記クラスを。 - それを実行し、それがNPEをスローする必要があります。
- 呼び出しを削除する
Object.getClass
からOuter.class
(例えば任意のバイトコード・エディタを使用してJBE)。 - もう一度プログラムを実行し、それが正常に完了します。