web-dev-qa-db-ja.com

2つの列挙値を '<'と比較できないのはなぜですか。

列挙型がComparableを実装しているのに、なぜ<または>と比較できないのですか?

public class Dream    
{
    public static void main(String... args)
    {
        System.out.println(PinSize.BIG == PinSize.BIGGER); //false
        System.out.println(PinSize.BIG == PinSize.BIG); //true
        System.out.println(PinSize.BIG.equals(PinSize.BIGGER));//false
        System.out.println(PinSize.BIG > PinSize.BIGGERER);// compilation error
        //can't be compared
        System.out.println(PinSize.BIG.toString().equals(PinSize.BIGGER));// #4
        PinSize b = PinSize.BIG ;
        System.out.println( b instanceof Comparable);// true
    }  
}
enum PinSize { BIG, BIGGER, BIGGERER };
26
Joe

あなたはこれを行うことができます:

PinSize.BIGGEST.ordinal() > PinSize.BIG.ordinal()  // evaluates to `true`

もちろん、列挙でBIGGESTが宣言されたと仮定するとafterBIGになります。列挙の序数値は暗黙的に宣言の順序に関連付けられます。デフォルトでは、最初の値には値0、2番目の値には1などが割り当てられます。

したがって、次のように列挙型を宣言した場合、問題はありません。

public enum PinSize {
    SMALLEST,  // ordinal value: 0
    SMALL,     // ordinal value: 1
    NORMAL,    // ordinal value: 2
    BIG,       // ordinal value: 3
    BIGGER,    // ordinal value: 4
    BIGGEST;   // ordinal value: 5
}
43
Óscar López

Comparableを実装しないとは、<または>を使用できることを意味します。 onlyを数値で使用できます。

Comparable を実装すると、 compareTo() メソッドが存在することになります。これを試して:

System.out.println(PinSize.BIG.compareTo(PinSize.BIGGER));

compareTo() メソッドは、「より大きい」値に応じて、0よりも小さい、等しい、または大きいintを返します。 enum値の場合、「サイズ」は列挙値の定義の順序に依存します。

17
Joachim Sauer

提供された回答は問題をよく説明していますが、「<または>と比較できないのはなぜですか?」という質問には答えないので、洞察を加えたいと思います。問題はリファレンスの比較に帰着します。 PinSize.BIGGESTとPinSize.BIGGERERは参照変数です。以下と同じ:

String s;
int[] array;
MyObject myObject;

それらはメモリ内のアドレスを表します。さらに、列挙型はシングルトンなので、指定した種類のオブジェクトは常に1つ存在します。そのため、以下の行が許可され、trueを返します。

System.out.println(PinSize.BIG == PinSize.BIG); //true

メモリ内の1つのアドレスがメモリ内の他のアドレスより大きいか小さいかを確認しようとすることは不可能です。 ComparableインターフェイスとcompareTo()メソッドを実装すると、メモリ内のアドレスではなくオブジェクトを比較する独自のカスタム方法を提供する機会が与えられます。

System.out.println(PinSize.BIG > PinSize.BIGGERER); // not possible
1
MrKiller21