2012-04-10 14 views
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の本で見つけました。このコードはNPEの代わりに1を出力します。誰かが同じ理由を説明してもらえますか?なぜこのコードはNullPointerExceptionを返しませんか?

答えて

18

Java Language Specificationに応じなければならないように、それは動作します。

null参照例外を引き起こすことなく、クラス(静的)変数にアクセスするために使用することができます。

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); 

?現在の "もちろん" ...

6

スタティックメソッド呼び出しはコンパイル時に解決されます。コンパイラでは、A型の戻り値があり、静的なgetValue()メソッド(同じ名前のインスタンスメソッドはありません)があるので、バイトコードでは実際の戻り値はgetNull()で無視され、A.getValue()が呼び出されます。

1

getNull関数はAオブジェクトを返します。 getValueはstaticとして宣言され、A.getValue()の場合と同様に、機能するにはclass_nameが必要です。 getNullはAオブジェクトを返します(実際には)... 1

1

System.out.println(m.getNull()。getValue()); このコードは次のコード行と同じです。 System.out.println(A.getValue()); のgetValue()メソッドは静的であり、そしてためなど

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

+1

これは間違っています、 'm.getNull呼び出されます。ジョンの答えを見てください。 – assylias

+0

m.getNull()は、getNullが静的でない場合にのみ呼び出されます。私は前に述べた。 –

+1

私は、 'System.out.println(m.getNull()。getValue());'は 'System.out.println(A.getValue());'と同じではありません。 'm.getNull();と同じです。 System.out.println(A.getValue()); '。 – assylias

関連する問題