Javaのnull参照の静的フィールド


119

staticJavaのメンバー(staticフィールドまたはstaticメソッド)は、このクラスのオブジェクトではなく、それぞれのクラスに関連付けられています。次のコードは、null参照の静的フィールドにアクセスしようとします。

public class Main
{
    private static final int value = 10;

    public Main getNull()
    {
        return null;
    }

    public static void main(String[] args)
    {
        Main main=new Main();
        System.out.println("value = "+main.getNull().value);
    }
}

main.getNull()戻ってnull、それが動作して表示value = 10。このコードはどのように機能しますか?



4
楽しみにしてみてくださいMain main = null; main.getNull().value
Marko Topolnik、2012

1
これはnew Thread[]{}[-1].sleep(10);、sleep()が静的メソッドである場所を思い出させます。これは、以前の一部のJavaバージョンでは成功していました。
hertzsprung 2012

回答:


93

この動作は、Java言語仕様で指定されています

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

より詳細には、静的フィールド評価はPrimary.staticField次のように機能します(強調は私のものです)-あなたの場合Primary = main.getNull()

  • 1次式が評価され、結果は破棄されます。[...]
  • フィールドが非空白の最終フィールドの場合、結果は、クラスまたはインターフェイスで指定されたクラス変数の値であり、一次式のタイプになります。[...]

5
この選択が行われた理由について誰かが情報を持っている場合、それは興味深いでしょう。

6
@JonofAllTradesこれは明白だと思います。メソッドは静的なので、null参照を呼び出すときに例外をスローしないことは問題ではないため、妥当です。
Malcolm

13
@JonofAllTrades:本当の質問は、静的メンバーをインスタンスとして呼び出すことを許可するという選択がなされた理由です...私には、それは混乱と読みにくいコードにつながるように見えます。
Falanwe 2012

2
@Falanwe:同意し、それは私が必要としなかった構成ですが、私はほとんど許可されていない.NETで作業します。親クラスへの参照が与えられたときに、サブクラスの適切な静的メソッドを呼び出したいと思うかもしれません。

8
@Falanweこれは許可されていますが、Eclipseでは「静的フィールドMain.valueには静的な方法でアクセスする必要があります」という警告が表示されます。少なくとも警告(私のように)にこだわる人は、そのようなコードを避けます。
Artyom 2012

19

あなたが言ったように、静的フィールドはインスタンスに関連付けられていないからです。

(あなたがしているように)インスタンス参照から静的フィールドにアクセスする機能は、単なる構文上の砂糖であり、追加の意味はありません。
コードは次のようにコンパイルされます

main.getNull(); 
Main.value

7
私はそれを構文砂糖と呼びます。構文の
おがくずの

3

コンパイル時にオブジェクトを含む静的変数またはメソッドにアクセスすると、クラス名に変換されます。例えば:

Main main = null;
System.out.println(main.value);

コンパイル時に変換されるため、静的変数値の値を出力します

System.out.println(Main.value);

証明:

逆コンパイラをダウンロードして、.classファイルを.javaファイルに逆コンパイルすると、すべての静的メソッドまたは変数参照オブジェクト名が自動的にクラス名に置き換えられていることがわかります。


3
  1. staticクラス名でメンバーにアクセスすることは正当ですがstatic、オブジェクト参照変数を使用してメンバーにアクセスできないことは書かれていません。つまり、ここで機能します。

  2. nullオブジェクト参照変数がアクセスすることを許可されているstaticいずれかのコンパイル、または実行時に例外をスローすることなく、クラス変数を。


2

静的変数とメソッドは常にクラスに属します。したがって、オブジェクトを作成すると、静的でない変数とメソッドのみがオブジェクトとともにヒープに移動しますが、静的はクラスを持つメソッド領域に存在します。そのため、静的変数またはメソッドにアクセスしようとすると、クラス名のドット変数またはメソッド名に変換されます。

詳細については、以下のリンクを参照してください。

http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.