2016-04-03 27 views
5

私がこのquizで見つけたこのタスクについて、どのように説明したいと思いますか? getFooメソッドがnullを返しても、出力はまだGetting Object JavaQuizです。私はそれがNullPointerExceptionであるべきだと思います。ヌルオブジェクトで静的メソッドを呼び出す

public class Foo { 

     static String name = " JavaQuiz"; 

     static Foo getFoo() { 
      System.out.print("Getting Object"); 
      return null; 
     } 

     public static void main(String[] args) { 
      System.out.println(getFoo().name); 
     } 

    } 

答えて

11

静的メソッドまたは変数にアクセスするには、その静的メソッド/変数を含むクラスのnull参照を使用できます。 nameので

getFoo().nameに関係なくgetFoo()かどうかを返しnullFoo.nameまたは単にname、同様の結果を有し、静的です。

ただし、静的メソッド/変数にアクセスするときは、静的メンバーにアクセスすることを明示しているので、常にクラス名を使用する方が良いです。 class

+1

私は、これはおそらくSOに書き込むコメントの種類ではないことを知っています。しかし、あなたの知識は本当に驚異的です。常にあなたの答えから学ぶ。 :) –

2

staticメンバーはjvmclassloaderがクラスをロードするときに自動的にロードされたこれらのstatic Members.`

にアクセスするためのオブジェクトの必要がないその手段classレベルのメンバーです。そこでここでは、この場合の

static String name = " JavaQuiz"; //load when class get loaded by JVM class loader. 

このstatic変数意志がクラスFoojvmにロード取得された直後のメモリに存在します。

static Foo getFoo() { //method is also a static Member automatically loaded at Class Loading. 
      System.out.print("Getting Object"); 
      return null; 
     } 

この静的メソッドgetFoo()でも同じことが適用されます。

だからSystem.out.println(getFoo().name);です。ここ は私の答えをabbriviateする例である

class StaticExample 
{ 
    static String abc ="India"; 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     StaticExample obj = null; 
     System.out.println("Value is ==>" + obj.abc + StaticExample.abc + abc); 
    } 
} 

出力: -

ここ
Value is ==>IndiaIndiaIndia 

のコード行も出力を生成します。

 System.out.println(((Ideone)null).abc); // this will also print India. 

出力: -

Value is ==>India 

注: - .nameが曖昧になる場合、私は混乱についてgetFoo()方法があると思いますが。 nameはスタティックメンバーなので、classNameまたはnullという参照を使用してアクセスできます。したがって、ここでは、このname変数にすべてのnull参照でアクセスするような状況が想定されます。

希望があります。

0

(javap -c Foo)を逆アセンブルすると、namestaticのときにNullPointerExceptionが表示されない理由がFoo.javaファイルのバイトコードによって明らかになります。

上記のコードでは、逆アセンブルすると次の出力が生成されます。

With Static field

我々は黄色のボックスを見れば、私たちは、コンパイラは、我々は、静的フィールドにアクセスしようとしていることを識別し、それがフィールドnameを取得するgetstatic命令を配置することを参照してください。だからこれはnameフィールドの値を取得するためにgetFooメソッドから返されたインスタンスを効果的に使用しないので、NPEは生成されません。


我々はString name = " JavaQuiz";staticキーワードを削除した場合、それは逆アセンブルコードの下での結果。ここで

Without static keyword

我々はJavaコンパイラはgetfield命令を使用すると、これはすなわち、getFooメソッドから返されたインスタンス上で呼び出さう指示見ることができます。したがって、が返された場合、NPEが発生します。

この場合、Javaコンパイラはコンパイル時に魔法を実行します。つまり、コードが静的フィールドを呼び出す場合は、オブジェクト参照を使用しないgetstatic命令を配置します。

命令セットhereに関する詳細情報があります。

関連する問題