19

次のような列挙型がある場合

enum Coffee {
    BIG,
    SMALL
}

列挙型の次のようなインスタンス変数を持つクラス:

public class MyClass {
    private Coffee coffee;

    // Constructor etc.
}

コンストラクターでたとえば言うことができるのはなぜcoffee.BIGですか?参照が使えるかわかりませんか?インスタンス変数としての列挙型は、他のものに初期化されていますnullか?これは、第1章のSCJPブックのセルフテストの質問#4です。コードと質問を短くしてみました。

4

3 に答える 3

21

enum Coffee {
    BIG,
    SMALL
}

BIGまたはSMALLはpublic static finalCoffeeクラスのフィールドであり、すべての静的フィールドと同様に、次のようなクラス名でアクセスできます。

Coffee b1 = Coffee.BIG;

または、クラスと同じタイプの参照によって、

Coffee s2 = b1.SMALL;
Coffee s3 = Coffee.BIG.SMALL; //BIG is reference of type Coffee so it is OK (but looks strange)

ただし、参照を介して静的メンバーにアクセスすることは避けてくださいインスタンスのメンバーではなくクラスのメンバーに実際にアクセスしているため、これにより混乱が生じます(たとえば、ポリモーフィックな動作はありません)。

于 2012-08-04T13:31:02.617 に答える
14

これは舞台裏で起こることです:

E:\workspace>type Coffee.java
public enum Coffee {
    BIG,
    SMALL
}

E:\workspace>javap Coffee
Compiled from "Coffee.java"
public final class Coffee extends java.lang.Enum<Coffee> {
  public static final Coffee BIG;
  public static final Coffee SMALL;
  public static Coffee[] values();
  public static Coffee valueOf(java.lang.String);
  static {};
}

ご覧BIGのとおり、列挙型でSMALLは本質的に静的フィールドです。

JLSもこの部分を明確にしています:

列挙型Eが列挙型から継承するメンバーに加えて、nという名前の宣言された列挙型定数ごとに、列挙型には、タイプEのnという名前の暗黙的に宣言されたパブリック静的最終フィールドがあります。これらのフィールドは、列挙型で明示的に宣言された静的フィールドの前の、対応する列挙定数と同じ順序。このような各フィールドは、それに対応する列挙型定数に初期化されます。

これがあなたの質問を明確にすることを願っています。

于 2012-08-04T13:30:11.280 に答える
6

Java 5より前は、列挙型を実装する方法は、特定の値に初期化された同じクラスのプライベートコンストラクターとパブリックfinalフィールドを使用してクラスを作成することでした。

Java 5以降、enumコンストラクトは事実上同じことを行うシュガーであり、null値が許可されていない、enum値がパブリック静的フィールドになるなどの処理を行います。

于 2012-08-04T13:02:55.277 に答える