5

私はそれが列挙型で凝灰岩であると感じています。これはキャシーシエラの本からの例です:

    public class WeatherTest {

    static Weather w;

    public static void main(String[] args) {
        System.out.print(w.RAINY.count + " " + w.Sunny.count + " ");
    }
}

enum Weather {

    RAINY, Sunny;
    int count = 0;

    Weather() {
        System.out.print("c ");
        count++;
    }
}

出力はcc11です。わかりました。ここで、カウントフィールドが静的である場合はどうなるでしょうか。出力はcc22になりますか?これに基づいて、count変数をstaticに変更しました。しかし、私が見るのはこれです:コンパイル時エラー:初期化子からの静的フィールドへの不正な参照。

ネットで検索すると、これはSunによるある種の抜け穴であり、静的フィールドを変更できる静的メソッドが可能であることがわかりました。わかりました。これで、静的メソッドincrを使用して仕事をします。

     class WeatherTest {

    static Weather w;

    public static void main(String[] args) {
        System.out.print(w.RAINY.count + " " + w.Sunny.count + " ");
    }
}

enum Weather {

    RAINY, Sunny;

    Weather() {
        System.out.print("c ");
        incr();
    }
    static int count = 0;

    static void incr() {
        count++;
    }
}

驚いたことに、次の出力が得られます:cc 0 0!私が自分を撃つ前に、誰かがこの行動を私に説明してもらえますか?

4

1 に答える 1

6

列挙値は、美化された静的フィールドと考えることができます (それらはカバーの下にあります)。

したがって、Weather通常の Java クラスであれば、次のようになります。

 class Weather {
   public final static Weather RAINY = new Weather( );
   public final static Weather Sunny = new Weather( );

   static int count = 0;

   Weather( ) {
     System.out.print("c ");
     incr();
   }

   static void incr()
   {
      count++;
   }
 }

両方の列挙値の後に宣言されていることがわかります。つまり、両方の値が作成された後にも初期count化されますまた、初期化されていない静的変数に遭遇した各関数呼び出しは、それをデフォルト値で初期化されたものとして扱います (それの)。int0

incrが適切に初期化された後に呼び出すことはないためcount、その値はまだ0

于 2012-07-20T16:37:17.930 に答える