16
public class Main
{
   public static void main(String []ar)
   {
      A m = new A();
      System.out.println(m.getNull().getValue());
   }
}

class A
{
   A getNull()
   {
      return null;
   }

   static int getValue()
   {
      return 1;
   }
}

私はSCJPの本でこの質問に出くわしました。1予想どおり、NPEの代わりにコードが出力されます。誰かが同じ理由を説明してもらえますか?

4

5 に答える 5

22

基本的に、静的メソッドをインスタンスメソッドであるのように呼び出しています。これは静的メソッド呼び出しに解決されるだけなので、次のように記述したかのようになります。

A m = new A();
m.getNull();
System.out.println(A.getValue());

IMOは、コードがまったく合法であるという事実は、Javaの設計上の欠陥です。それはあなたが非常に誤解を招くコードを書くことを可能にしますThread.sleep、例として私はいつも使用します:

Thread thread = new Thread(someRunnable);
thread.start();
thread.sleep(1000);

それはどのスレッドをスリープに送信しますか?現在のもの、「もちろん」...

于 2012-04-10T11:43:03.800 に答える
18

Java 言語仕様に従って動作します。

null 参照を使用して、例外を発生させずにクラス (静的) 変数にアクセスできます。

于 2012-04-10T11:45:49.447 に答える
6

静的メソッド呼び出しはコンパイル時に解決されます。コンパイラは、静的メソッドを持つ(同じ名前のインスタンス メソッドがない)getNull()型の戻り値があることを認識します。そのため、バイトコードでは、実際の戻り値は無視され、呼び出されます。AgetValue()getNull()A.getValue()

于 2012-04-10T11:45:40.103 に答える
1

System.out.println(m.getNull().getValue()); このコード行は System.out.println(A.getValue());と同じです。

getValue()メソッドは静的であり、すべての静的呼び出しは Java でコンパイル時に開始されるためです。したがって、 getValue()を非静的にすると、エラーは発生しません。これは、実行時に呼び出されるため、エラーが発生します

于 2012-04-10T12:00:51.367 に答える
1

getNull 関数は A オブジェクトを返します。getValue は static として宣言されており、A.getValue() のように class_name だけが機能する必要があります。getNull は(実際には) A オブジェクトを返すため... 1を取得します

于 2012-04-10T11:46:36.417 に答える