web-dev-qa-db-ja.com

null参照で(静的)メソッドを呼び出してもNullPointerExceptionがスローされないのはなぜですか?

私はこのプログラムをJavaで書きました

public class Why {

  public static void test() {
    System.out.println("Passed");
  }

  public static void main(String[] args) {
    Why NULL = null;
    NULL.test();
  }

}

nullオブジェクトでメソッドを呼び出すとNullPointerExceptionが発生することを読みましたが、上記のプログラムでは発生しませんか?どうしてこれなの?私は何かを正しく理解していませんか?

50
Artjem

test()staticメソッドです。 staticメンバーはタイプに属し、アクセスするためにインスタンスを必要としません。

staticメンバーは、型式を介して[〜#〜] only [〜#〜]にアクセスする必要があります。つまり、次のように書く必要があります。

Why.test(); // always invoke static method on the type it belongs to!

Javaでは、オブジェクト参照式を介してstaticメンバーにアクセスできますが、これは[〜#〜] very [〜#〜]これは[〜#〜]ではない[〜#〜]staticメンバーアクセスの実際のセマンティクスであるため、誤解を招く可能性があります。

Why aNull = null; 
aNull.test(); // DO NOT EVER DO THIS!
// invokes Why.test(), does NOT throw NullPointerException

オブジェクト参照式を介してstaticメンバーにアクセスする場合、宣言されたタイプの参照のみが重要です。この意味は:

  • インスタンスは必要ないため、参照が実際にnullであるかどうかは関係ありません。
  • 参照がnullでない場合、オブジェクトの実行時型が何であるかは関係ありません動的ディスパッチはありません! !!

ご覧のとおり、インスタンスメンバーアクセスの両方のポイントで正反対のことが当てはまります。これが、staticメンバーが[〜#〜]決して[〜#〜]に「非static "方法、それは実際に何をしているかについて非常に誤解を招くような外観を与えるからです。

関連する質問

79

IDEでさまざまな警告をオンにする必要があります。非静的な方法で静的メンバーにアクセスすることについての警告が表示される可能性があります。

(Why)(null).test()のようなことをすることができます、それはクラスを取得するために(Why)(null)だけを使用しています。

3
MrJacqes

静的メソッドは、オブジェクトへの参照を必要としません。したがって、オブジェクトへの参照がnullであっても呼び出すことができます。これがmainメソッドの仕組みです。

オブジェクトから静的指定を削除して、nullポインタの例外を確認してください。

3
Vlad

これは静的メソッドであり、インスタンスをインスタンス化せずにメソッドを呼び出すことができます。

3
JohnFx

静的変数とメソッドは、オブジェクトではなく、クラスに関連付けられています。クラスのすべてのインスタンスは、メモリ内の1つの固定された場所にあるクラス変数を共有します。

どのオブジェクトでもクラス変数の値を変更できますが、クラスのインスタンスを作成せずにクラス変数を操作することもでき、静的メソッドにも同じことが当てはまります。詳細については これを参照

1
Rupesh Yadav