コンパイラが enum に特別なメソッドを追加する理由。
基本的に、列挙型の値を簡単に取得できるようにします。
追加のメソッドはvalueOf
とだけvalues
です。さらに、その型の値の制約されたセットに実際にアクセスできるように、型の値ごとに 1 つずつpublic static final fieldsがあります。
コンパイラがandメソッド (または少なくともメソッド) を追加しなかったと想像してみてください。「列挙型のすべての値」にどのようにアクセスしますか? 多くの場合、これは便利なことです。valueOf
values
values
同様の機能が提供されるようになりましEnumSet
たが、「すべての値」を取得するには、Class<>
参照を提供する必要があり、面倒な場合があります。このvalues
メソッドは、呼び出すのがいくぶん簡単です (ただし、コストが高くなる可能性もあります)。
提供される内容の詳細については、JLS セクション 8.9を参照してください。
値の保存方法の問題に答えるために、値ごとに静的フィールドがあることが指定されていますが、実装の詳細として、Oracle Java コンパイラには配列を含む静的フィールドも含まれています。その配列は基本的にvalues
メソッドで複製されます。
これは自分で確認できます。
enum Foo {
BAR, BAZ;
}
コンパイル:
javac Foo.java
逆コンパイル:
javap -private Foo
Compiled from "Foo.java"
final class Foo extends java.lang.Enum<Foo> {
public static final Foo BAR;
public static final Foo BAZ;
private static final Foo[] $VALUES;
public static Foo[] values();
public static Foo valueOf(java.lang.String);
private Foo();
static {};
}
使用すると、基本的に次のjavap -c
ことがわかります。values()
public static Foo[] values() {
return (Foo[]) $VALUES.clone();
}
静的初期化ブロックは、限定されたインスタンスのセットを作成し、フィールドを設定します。