サーチ…


前書き

Java enums( enumキーワードを使用して宣言されています)は、単一クラスの大量の定数の簡略構文です。

構文

  • [public / protected / private] enum Enum_name {//新しい列挙型を宣言します。
  • ENUM_CONSTANT_1 [、ENUM_CONSTANT_2 ...]; // enum定数を宣言します。これは列挙型の内部の最初の行でなければならず、末尾にセミコロンを付けてカンマで区切る必要があります。
  • ENUM_CONSTANT_1(param)[、ENUM_CONSTANT_2(param)...]; //パラメータでenum定数を宣言します。パラメータ型はコンストラクタと一致する必要があります。
  • ENUM_CONSTANT_1 {...} [、ENUM_CONSTANT_2 {...} ...]; //オーバーライドされたメソッドで列挙型定数を宣言します。 enumに抽象メソッドが含まれている場合は、これを行う必要があります。そのような方法はすべて実装されなければならない。
  • ENUM_CONSTANT.name()// enum定数の名前のStringを返します。
  • ENUM_CONSTANT.ordinal()//この列挙定数の序数を返します。その列挙定数の位置は、初期定数にゼロの序数が代入されます。
  • Enum_name.values()//呼び出されるたびにその列挙型のすべての定数を含む新しい配列(Enum_name []型)を返します。
  • Enum_name.valueOf( "ENUM_CONSTANT")// ENUM_CONSTANT.name()の逆数 - 与えられた名前の列挙定数を返します。
  • Enum.valueOf(Enum_name.class、 "ENUM_CONSTANT")//前のものと同義語:ENUM_CONSTANT.name()の逆数 - 与えられた名前の列挙定数を返します。

備考

制限事項

列挙型は常にjava.lang.Enumを拡張しているため、クラスを拡張する列挙型は不可能です。ただし、多くのインターフェイスを実装できます。

ヒントとコツ

彼らの特殊な表現のために、enumをキーとして使用できるより効率的なマップセットがあります。これらは、非専門のカウンターパートよりも頻繁に速く実行されます。

宣言と基本列挙型の使用

Enumは、一連の定数を定義するためにコンパイル時に知られている何回かだけインスタンス化される密封クラスの構文シュガーと考えることができます。

さまざまな季節を列挙する簡単な列挙は、次のように宣言されます。

public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

列挙型定数は必ずしも大文字である必要はありませんが、定数の名前は完全に大文字で、単語はアンダースコアで区切られています。


Enumを独自のファイルに宣言できます:

/**
 * This enum is declared in the Season.java file.
*/
public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

しかし、別のクラスの中で宣言することもできます:

 public class Day {

    private Season season;

    public String getSeason() {
        return season.name();
    }

    public void setSeason(String season) {
        this.season = Season.valueOf(season);
    }

    /**
     * This enum is declared inside the Day.java file and 
     * cannot be accessed outside because it's declared as private.
     */
    private enum Season {
        WINTER,
        SPRING,
        SUMMER,
        FALL
    }

}

最後に、メソッド本体またはコンストラクタ内でEnumを宣言することはできません。

public class Day {

    /**
     * Constructor
    */
    public Day() {
        // Illegal. Compilation error
        enum Season {
            WINTER,
            SPRING,
            SUMMER,
            FALL
        }
    }

    public void aSimpleMethod() {
        // Legal. You can declare a primitive (or an Object) inside a method. Compile!
        int primitiveInt = 42;

        // Illegal. Compilation error.
        enum Season {
            WINTER,
            SPRING,
            SUMMER,
            FALL
        }

        Season season = Season.SPRING;
    }
    
}

重複する列挙定数は使用できません:

public enum Season {
    WINTER,
    WINTER, //Compile Time Error : Duplicate Constants
    SPRING,
    SUMMER,
    FALL
} 

enumのすべての定数は、デフォルトでpublicstaticおよびfinalです。すべての定数はstaticので、列挙型の名前を使用して直接アクセスできます。

列挙型定数は、メソッドパラメータとして渡すことができます:

public static void display(Season s) {
    System.out.println(s.name());  // name() is a built-in method that gets the exact name of the enum constant
}

display(Season.WINTER);  // Prints out "WINTER"

values()メソッドを使用して、列挙定数の配列を取得できます。値は、返される配列の宣言順になることが保証されています。

Season[] seasons = Season.values();

注:このメソッドは、呼び出されるたびに新しい値の配列を割り当てます。


列挙定数を反復するには:

public static void enumIterate() {
    for (Season s : Season.values()) {
        System.out.println(s.name());
    }
}

switch文でenumを使用できます。

public static void enumSwitchExample(Season s) {
    switch(s) {
        case WINTER:
            System.out.println("It's pretty cold");
            break;
        case SPRING:
            System.out.println("It's warming up");
            break;
        case SUMMER:
            System.out.println("It's pretty hot");
            break;
        case FALL:
            System.out.println("It's cooling down");
            break;
    }
}

==を使用してenum定数を比較することもできます。

Season.FALL == Season.WINTER    // false
Season.SPRING == Season.SPRING  // true

列挙型定数を比較するもう1つの方法は、次のように落とし穴に簡単に入ることができるので、悪い習慣とみなされる以下のようにequals()を使うことです:

Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error

内のインスタンスの集合がまた、 enum実行時に変更することができない他のクラスと同様に、ので、インスタンス自体が本質的に不変でないenum以下に示されているように可変フィールドを含むことができます。

public enum MutableExample {
    A,
    B;

    private int count = 0;

    public void increment() {
        count++;
    }

    public void print() {
        System.out.println("The count of " + name() + " is " + count);
    }
}

// Usage:
MutableExample.A.print();       // Outputs 0
MutableExample.A.increment();
MutableExample.A.print();       // Outputs 1 -- we've changed a field   
MutableExample.B.print();       // Outputs 0 -- another instance remains unchanged

しかし、良い例は、 enumインスタンスを不変にすることです。つまり、追加のフィールドを持たない場合や、すべてのフィールドがfinalとマークされていて不変の場合です。これにより、アプリケーションの存続期間中、 enumはメモリをリークさせず、すべてのスレッドにわたってそのインスタンスを使用することが安全であることを保証します。


Enumクラスは以下のことを行うため、 Enum型は暗黙的にSerializableComparable実装します。

public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable

コンストラクタを持つ列挙型

enumはpublicコンストラクタを持つことはできません。ただし、privateコンストラクタは受け入れられます(enumのコンストラクタはデフォルトでpackage-privateです)。

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25); // usual names for US coins
    // note that the above parentheses and the constructor arguments match
    private int value;

    Coin(int value) { 
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

int p = Coin.NICKEL.getValue(); // the int value will be 5

列挙型のインスタンスは限られているので、すべてのフィールドを非公開にしてゲッターメソッドを提供することをお勧めします。


Enumclassとして実装する場合、次のようになります。

public class Coin<T extends Coin<T>> implements Comparable<T>, Serializable{
    public static final Coin PENNY = new Coin(1);
    public static final Coin NICKEL = new Coin(5);
    public static final Coin DIME = new Coin(10);
    public static final Coin QUARTER = new Coin(25);

    private int value;

    private Coin(int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

int p = Coin.NICKEL.getValue(); // the int value will be 5

Enum定数は技術的に変更可能であるため、enum定数の内部構造を変更するためにsetterを追加することができます。しかし、これは非常に悪い習慣と考えられ、避けるべきです。

ベストプラクティスは、Enumフィールドをfinal不変にすることです。

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    private final int value;

    Coin(int value){ 
        this.value = value;
    }

    ...

}

同じ列挙型で複数のコンストラクタを定義することができます。あなたがするとき、あなたのenum宣言で渡す引数は、呼び出されるコンストラクタを決定します:

public enum Coin {
    PENNY(1, true), NICKEL(5, false), DIME(10), QUARTER(25);

    private final int value;
    private final boolean isCopperColored;

    Coin(int value){
        this(value, false);
    }

    Coin(int value, boolean isCopperColored){ 
        this.value = value;
        this.isCopperColored = isCopperColored;
    }

    ...

}

注: EnumクラスはSerializableを実装する必要があります。

メソッドとスタティックブロックの使用

列挙型には、すべてのクラスと同様に、メソッドを含めることができます。これがどのように動作するかを確認するために、次のようなenumを宣言します:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;
}

列挙型を逆方向に返すメソッドを用意しましょう:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;

    public Direction getOpposite(){
        switch (this){
            case NORTH:
                return SOUTH;               
            case SOUTH:
                return NORTH;                
            case WEST:
                return EAST; 
            case EAST:
                return WEST;  
            default: //This will never happen
                return null;
        }
    }
}

これは、フィールドと静的イニシャライザブロックを使用することでさらに改善できます。

public enum Direction {
    NORTH, SOUTH, EAST, WEST;
    
    private Direction opposite;
    
    public Direction getOpposite(){
        return opposite;
    }
    
    static {
        NORTH.opposite = SOUTH;
        SOUTH.opposite = NORTH;
        WEST.opposite = EAST;
        EAST.opposite = WEST;
    }
}

この例では、反対方向をプライベートインスタンスフィールドに格納されているopposite静的初めて初期化され、 Direction使用されます。 (ので、この特定のケースではNORTH参照SOUTHと逆に)、我々が使用することはできませんコンストラクタを持つ列挙型 (ここでコンストラクタNORTH(SOUTH), SOUTH(NORTH), EAST(WEST), WEST(EAST)よりエレガントになるとできるようになりoppositeしますfinalに宣言されるが、自己参照となり、したがって許可されない)。

インターフェースを実装する

これは、プリコンパイルされた正規表現パターンに対してString入力をテストする呼び出し可能な関数でもあるenumです。

import java.util.function.Predicate;
import java.util.regex.Pattern;

enum RegEx implements Predicate<String> {
    UPPER("[A-Z]+"), LOWER("[a-z]+"), NUMERIC("[+-]?[0-9]+");

    private final Pattern pattern;

    private RegEx(final String pattern) {
        this.pattern = Pattern.compile(pattern);
    }

    @Override 
    public boolean test(final String input) {
        return this.pattern.matcher(input).matches();
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(RegEx.UPPER.test("ABC"));
        System.out.println(RegEx.LOWER.test("abc"));
        System.out.println(RegEx.NUMERIC.test("+111"));
    }
}

列挙型の各メンバーは、このメソッドを実装することもできます。

import java.util.function.Predicate;

enum Acceptor implements Predicate<String> {
    NULL {
        @Override
        public boolean test(String s) { return s == null; }
    },
    EMPTY {
        @Override
        public boolean test(String s) { return s.equals(""); }
    },
    NULL_OR_EMPTY {
        @Override
        public boolean test(String s) { return NULL.test(s) || EMPTY.test(s); }
    };
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Acceptor.NULL.test(null));  // true
        System.out.println(Acceptor.EMPTY.test(""));   // true
        System.out.println(Acceptor.NULL_OR_EMPTY.test(" ")); // false
    }
}

列挙型多型パターン

この方法は、の「拡張可能な」セット受け入れる必要がある場合enum値を、プログラマは、通常の上のような多型を適用することができるclassここanywere使用されるインタフェース作成することにより、 enum Sを使用しなければならないが。

public interface ExtensibleEnum {
    String name();
}

このようにして、インタフェースによってタグ付け(実装)されたenumパラメータとして使用することができ、プログラマはメソッドによって受け入れられる可変量のenum型を作成することができます。これは、例えば、デフォルトの(変更不可能な) enumがあるAPIにおいて有用であり、これらのAPIのユーザは、より多くの値でenumを「拡張」したい。

デフォルトのenum値のセットは、次のように定義できます。

public enum DefaultValues implements ExtensibleEnum {
    VALUE_ONE, VALUE_TWO;
}

追加の値は次のように定義できます。

public enum ExtendedValues implements ExtensibleEnum {
    VALUE_THREE, VALUE_FOUR;
}

enum型の使用方法を示すサンプル - printEnum()が両方のenum型の値を受け入れる方法に注意してください:

private void printEnum(ExtensibleEnum val) {
    System.out.println(val.name());
}  

printEnum(DefaultValues.VALUE_ONE);    // VALUE_ONE
printEnum(DefaultValues.VALUE_TWO);    // VALUE_TWO
printEnum(ExtendedValues.VALUE_THREE); // VALUE_THREE
printEnum(ExtendedValues.VALUE_FOUR);  // VALUE_FOUR

注:このパターンは、別の列挙型で既に1つの列挙型で定義されている列挙型値を再定義することを妨げるものではありません。これらの列挙型の値は別のインスタンスになります。また、switch-on-enumを使用することはできません。これは、実際のenumではなくインターフェースであるからです。

抽象メソッドを持つ列挙型

列挙型は抽象メソッドを定義することができ、それぞれのenumメンバーは実装する必要があります。

enum Action {
    DODGE {
        public boolean execute(Player player) {
            return player.isAttacking();
        }
    },
    ATTACK {
        public boolean execute(Player player) {
            return player.hasWeapon();
        }
    },
    JUMP {
        public boolean execute(Player player) {
            return player.getCoordinates().equals(new Coordinates(0, 0));
        }
    };

    public abstract boolean execute(Player player);
}

これにより、各enumメンバは、最上位定義のメソッドの型をオンにすることなく、指定された操作に対して独自の動作を定義できます。

このパターンは、多態性および/またはインターフェイスの実装を使用して通常達成されるものの短い形式です。

enumを文書化する

必ずしもenum名が理解できるほど明確ではない。 enumを文書化するには、標準のjavadocを使用します。

/**
 * United States coins
 */
public enum Coins {
    
    /**
     * One-cent coin, commonly known as a penny, 
     * is a unit of currency equaling one-hundredth 
     * of a United States dollar
     */
    PENNY(1),

    /**
     * A nickel is a five-cent coin equaling 
     * five-hundredth of a United States dollar
     */        
    NICKEL(5),

    /**
     * The dime is a ten-cent coin refers to 
     * one tenth of a United States dollar
     */        
    DIME(10),

    /**
     * The quarter is a US coin worth 25 cents, 
     * one-fourth of a United States dollar
     */        
    QUARTER(25);

    private int value;

    Coins(int value){ 
        this.value = value;
    }

    public int getValue(){
        return value;
    }
}

列挙型の値を取得する

各enumクラスには、 values()という名前の暗黙の静的メソッドが含まれていvalues() 。このメソッドは、そのenumのすべての値を含む配列を返します。このメソッドを使用して値を反復処理することができます。ただし、このメソッドは呼び出されるたびに新しい配列を返すことに注意することが重要です。

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
    
    /**
    * Print out all the values in this enum.
    */
    public static void printAllDays() {
        for(Day day : Day.values()) {
            System.out.println(day.name());
        }
    }
}

Setが必要な場合は、 EnumSet.allOf(Day.class)も使用できます。

境界型パラメータとしての列挙型

ジェネリックのクラスをjavaに書くときには、typeパラメータがenumであることを保証することができます。すべての列挙型はEnumクラスを拡張するので、次の構文を使用できます。

public class Holder<T extends Enum<T>> {
    public final T value;

    public Holder(T init) {
        this.value = init;
    }
}

この例では、型T 列挙型でなければなりません

名前で定数を取得する

enum DayOfWeekがあるとしDayOfWeek

enum DayOfWeek {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

enumは組み込みの静的なvalueOf()メソッドでコンパイルされます。このメソッドは名前で定数を検索するために使用できます:

String dayName = DayOfWeek.SUNDAY.name();
assert dayName.equals("SUNDAY");

DayOfWeek day = DayOfWeek.valueOf(dayName);
assert day == DayOfWeek.SUNDAY;

これは、動的列挙型を使用しても可能です。

Class<DayOfWeek> enumType = DayOfWeek.class;
DayOfWeek day = Enum.valueOf(enumType, "SUNDAY");
assert day == DayOfWeek.SUNDAY;

指定されたenumに一致する名前の定数がない場合、これらのvalueOf()メソッドはどちらもIllegalArgumentExceptionをスローします。

Guavaライブラリは、明示的な例外処理を排除するためにGuava Optionalを返すヘルパーメソッドEnums.getIfPresent()を提供します。

DayOfWeek defaultDay = DayOfWeek.SUNDAY;
DayOfWeek day = Enums.valueOf(DayOfWeek.class, "INVALID").or(defaultDay);
assert day == DayOfWeek.SUNDAY;

単一要素列挙型でシングルトンパターンを実装する

列挙型定数は、列挙型が初めて参照されるときにインスタンス化されます。したがって、単一要素の列挙型でSingletonソフトウェア設計パターンを実装することができます。

public enum Attendant {

    INSTANCE;

    private Attendant() {
        // perform some initialization routine
    }

    public void sayHello() {
        System.out.println("Hello!");
    }
}


public class Main {

    public static void main(String... args) {
        Attendant.INSTANCE.sayHello();// instantiated at this point
    }
}

Joshua Blochの "Effective Java"の本によれば、単一要素列挙型がシングルトンを実装する最良の方法です。このアプローチには以下の利点があります。

  • スレッドの安全性
  • 単一インスタンス化の保証
  • すぐに使えるシリアル化

また、 インタフェースを実装するセクションに示すように、このシングルトンは1つ以上のインタフェースを実装することもできます。

プロパティ(フィールド)を持つ列挙型

私たちは、定数値だけでなく、より多くの情報でenumを使いたい場合、2つの列挙型を比較できるようにしたいと考えています。

次の例を考えてみましょう。

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    private final int value;

    Coin(int value){
        this.value = value;
    }

    public boolean isGreaterThan(Coin other){
        return this.value > other.value;
    }

}

ここでは、その値を表すCoinというEnumを定義しました。 isGreaterThanメソッドを使用すると、2つのenum isGreaterThanを比較できます。

Coin penny = Coin.PENNY;
Coin dime = Coin.DIME;

System.out.println(penny.isGreaterThan(dime)); // prints: false
System.out.println(dime.isGreaterThan(penny)); // prints: true

列挙型を文字列に変換する

列挙型をStringに変換する場合は、2つの方法があります。

我々が持っていると仮定:

public enum Fruit {
    APPLE, ORANGE, STRAWBERRY, BANANA, LEMON, GRAPE_FRUIT;
}

では、 Fruit.APPLEようなものをどうすれば"APPLE"変換できますか?


name()を使用して変換するname()

name()enum内部メソッドであり、 enumString表現を返します。戻りStringは、enum値がどのように定義されたかを正確に表します。

例えば:

System.out.println(Fruit.BANANA.name());      // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.name()); // "GRAPE_FRUIT"

toString()を使用して変換する

toString()は、 デフォルトでは、 name()と同じ動作をするようにオーバーライドされています

しかし、 toString()開発者によってオーバーライドされ、ユーザーフレンドリなString印刷しやすくなります

あなたのコードをチェックしたいなら、 toString()使わないでくださいtoString() name()はもっと安定しています。値をログや標準出力などに出力するときにのみtoString()使用します

デフォルトでは:

System.out.println(Fruit.BANANA.toString());      // "BANANA"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "GRAPE_FRUIT"

上書きされる例

System.out.println(Fruit.BANANA.toString());      // "Banana"
System.out.println(Fruit.GRAPE_FRUIT.toString()); // "Grape Fruit"

Enum定数の特定のボディ

enum特定の定数の具体的な動作を定義することが可能であるenumのデフォルトの動作オーバーライドenum 、この技術は、 一定の特定体として知られています。

John、Ben、Lukeの3人のピアノの生徒がPianoClassという名前のenum PianoClassで次のように定義されているとします。

    enum PianoClass {
    JOHN, BEN, LUKE;
        public String getSex() {
            return "Male";
        }
        public String getLevel() {
            return "Beginner";
        }
    }

そして1日2人の他の生徒、リタとトムがセックス(女性)とレベル(中級)で、以前のものと一致しない:

    enum PianoClass2 {
    JOHN, BEN, LUKE, RITA, TOM;
        public String getSex() {
            return "Male"; // issue, Rita is a female
        }
        public String getLevel() {
            return "Beginner"; // issue, Tom is an intermediate student
        }
    }

次のように、単に新しい宣言を定数宣言に追加するのは正しいとは限りません。

PianoClass2 tom = PianoClass2.TOM;
PianoClass2 rita = PianoClass2.RITA;
System.out.println(tom.getLevel()); // prints Beginner -> wrong Tom's not a beginner
System.out.println(rita.getSex()); // prints Male -> wrong Rita's not a male

PianoClass2デフォルトの動作を次のようにオーバーライドする定数RitaとTomのそれぞれの動作を定義することができます:

enum PianoClass3 {
    JOHN, BEN, LUKE,
    RITA {
        @Override
        public String getSex() {
            return "Female";
        }
    },
    TOM {
        @Override
        public String getLevel() {
            return "Intermediate";
        }
    };
    public String getSex() {
        return "Male";
    }
    public String getLevel() {
        return "Beginner";
    }
}

トムのレベルとリタのセックスは、次のようになります。

PianoClass3 tom = PianoClass3.TOM;
PianoClass3 rita = PianoClass3.RITA;
System.out.println(tom.getLevel()); // prints Intermediate
System.out.println(rita.getSex()); // prints Female

コンテンツ固有のボディを定義する別の方法は、コンストラクタを使用することです。

enum Friend {
    MAT("Male"),
    JOHN("Male"),
    JANE("Female");
    
    private String gender;

    Friend(String gender) {
        this.gender = gender;
    }

    public String getGender() {
        return this.gender;
    }
}

および使用法:

Friend mat = Friend.MAT;
Friend john = Friend.JOHN;
Friend jane = Friend.JANE;
System.out.println(mat.getGender());     // Male
System.out.println(john.getGender());    // Male
System.out.println(jane.getGender());    // Female

ゼロインスタンスの列挙型

enum Util {
    /* No instances */;

    public static int clamp(int min, int max, int i) {
        return Math.min(Math.max(i, min), max);
    }

    // other utility methods...
}

シングルトン (1インスタンスクラス)にenum を使用できるように、ユーティリティクラス(0インスタンスクラス)に使用できます。 enum定数の(空の)リストを必ず終了させて​​ください;

非公開のコンストラクタと比較して、プロと議論の議論のためのインスタンス化防ぐためのゼロインスタンスの列挙型とプライベートなコンストラクタの質問を参照してください。

静的フィールドを持つ列挙型

enumクラスに静的フィールドが必要な場合は、enum値自体のに作成されることに注意してください。つまり、次のコードではNullPointerExceptionます。

enum Example {
    ONE(1), TWO(2);

    static Map<String, Integer> integers = new HashMap<>();

    private Example(int value) {
        integers.put(this.name(), value);
    }
}

これを修正する方法は次のとおりです。

enum Example {
    ONE(1), TWO(2);

    static Map<String, Integer> integers;

    private Example(int value) {
        putValue(this.name(), value);
    }

    private static void putValue(String name, int value) {
        if (integers == null)
            integers = new HashMap<>();
        integers.put(name, value);
    }
}

静的フィールドを初期化しないでください:

enum Example {
    ONE(1), TWO(2);

    // after initialisisation integers is null!!
    static Map<String, Integer> integers = null;

    private Example(int value) {
        putValue(this.name(), value);
    }

    private static void putValue(String name, int value) {
        if (integers == null)
            integers = new HashMap<>();
        integers.put(name, value);
    }
    // !!this may lead to null poiner exception!!
    public int getValue(){
        return (Example.integers.get(this.name()));
    }
}

初期化:

  • 列挙型の値を作成する
    • 副作用として、putValue()が呼び出され、整数が初期化されます
  • 静的な値が設定されます。
    • 整数=ヌル; //列挙型の後に実行されるので、整数の内容は失われます

Enum値の比較とインクルード

Enumは定数のみを含み、 ==と直接比較できます。したがって、参照チェックのみが必要で、 .equalsメソッドを使用する必要はありません。さらに、 .equalsが正しく使用されていない場合、 NullPointerExceptionする可能性がありますが、これは== checkの場合には==ません。

enum Day {
    GOOD, AVERAGE, WORST;
}

public class Test {

    public static void main(String[] args) {
        Day day = null;

        if (day.equals(Day.GOOD)) {//NullPointerException!
            System.out.println("Good Day!");
        }

        if (day == Day.GOOD) {//Always use == to compare enum
            System.out.println("Good Day!");
        }

    }
}

EnumSetクラスをグループ化、補完、範囲指定するには、異なるメソッドを含むEnumSetクラスがあります。

  • EnumSet#range :2つのエンドポイントで定義された範囲でenumのサブセットを取得する

  • EnumSet#of :範囲を持たない特定のenumのセット。複数ofメソッドがオーバーロードされています。

  • EnumSet#complementOf :メソッドのパラメータで提供されるenum値を補完するenumのセット

    enum Page {
       A1, A2, A3, A4, A5, A6, A7, A8, A9, A10
    }
    
    public class Test {
    
      public static void main(String[] args) {
          EnumSet<Page> range = EnumSet.range(Page.A1, Page.A5);
    
          if (range.contains(Page.A4)) {
              System.out.println("Range contains A4");
          }
    
          EnumSet<Page> of = EnumSet.of(Page.A1, Page.A5, Page.A3);
    
          if (of.contains(Page.A1)) {
              System.out.println("Of contains A1");
          }
      }
    }
    


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow