web-dev-qa-db-ja.com

インスタンス変数としての列挙

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

enum Coffee {
    BIG,
    SMALL
}

そして、この列挙型のようなインスタンス変数を持つクラス:

public class MyClass {
    private Coffee coffee;

    // Constructor etc.
}

コンストラクタでなぜ言う​​ことが可能であるのですか? coffee.BIG?参照を使用できることを理解していませんか? enumはインスタンス変数としてnull以外に初期化されていますか?これは、第1章のSCJPブックのセルフテストの質問4です。 コードと質問を短くしようとしました

19
LuckyLuke

enum Coffee {
    BIG,
    SMALL
}

BIGまたはSMALLはpublic static final Coffeeクラスのフィールド。すべての静的フィールドと同様に、クラス名でアクセスできます。

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)

ただし、参照を介して静的メンバーにアクセスすることは避けてくださいであることを覚えておいてください。 instanceのメンバーではなくclassのメンバーにアクセスしているので、これは混乱を引き起こします(たとえば、多態的な動作はありません) 。

20
Pshemo

これは舞台裏で何が起こるかです

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 {};
}

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

[〜#〜] jls [〜#〜] もこの部分を明確にします。

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

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

13
Ajay George

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

Java 5であるため、enumコンストラクトは事実上同じことを行う砂糖であり、null値は許可されない、enum値はpublic staticフィールドなどになる).

5
01es