1
public class Document{
    private Integer status;

    // get()/set()
}

次に列挙型:

public enum DocumentStatusEnum {

        ACTIVE_DOCUMENT(2060),CANCELLED_DOCUMENT(2061),DRAFT_DOCUMENT(2062),PROCESSED_DOCUMENT(2063);

        private final Integer value;

        private DocumentStatusEnum(Integer value){
            this.value = value;
        }
        public Integer getValue(){
            return value;
        }
    }

メソッドでは、上記のメソッドを以下のように使用しています。

Document d = new Document();
d.setStatus(2063);
if (d.getStatus() == DocumentStatusEnum.PROCESSED_DOCUMENT.getValue()){
{
       // print true;
    }
    else{
       // print false;
    }

私はここで真実になります。大丈夫そうです。同じ方法で、数行後、次のようにします。

d.setStatus(2060)
if (d.getStatus() == DocumentStatusEnum.ACTIVE_DOCUMENT.getValue()){
   // print true
}
else{
   // print false

}

私は偽を取得します。Java のキャッシング機能とボクシング機能について調べたところ、何かが見つかりました。列挙型定義を次のように変換しました。

public enum DocumentStatusEnum {

    ACTIVE_DOCUMENT(2060),CANCELLED_DOCUMENT(2061),DRAFT_DOCUMENT(2062),PROCESSED_DOCUMENT(2063);

    private final int value;

    private DocumentStatusEnum(int value){
        this.value = value;
    }
    public int getValue(){
        return value;
    }
}

今、問題はありません。どちらの場合も真実になります。

質問は、なぜこれが起こっているのですか?この動作は非常に不安定だと思います。これは私が扱っている大規模なアプリケーションであり、Integer == Integerあらゆる場所で比較を使用しています。私はここで安全ですか?

4

2 に答える 2

6

IntegerObjectしたがって、値の等価性では==なく、参照の等価性として定義されます。

と比較するIntegerint、 はIntegerアンボックス化されてintになり、2 つのオペランドの値が等しいかどうかが比較されます。Integer(値がでない限り、nullその場合NullPointerExceptionは代わりにスローされます。)しかしInteger == Integer、決して安全ではありません。

とはいえ、デフォルトでは、ランタイムは小さな整数 ( OpenJDK ソースIntegerによると -128 から 127) のインスタンスを事前に割り当てるため、小さな値で作業できることがよくあります。しかし、その動作はより大きな値には当てはまらず、保持する必要はありません。したがって、明示的に参照の等価性を探している場合を除き、 (or 、または any ) の 2 つのインスタンスが を使用して同等であると想定しないでください。Integer == IntegerIntegerStringObject==

于 2013-01-03T00:46:43.043 に答える
3

null 値を処理する必要がない限り、intの代わりに を使用する必要があります。Integer

オブジェクトの比較には確かに問題がありIntegerます。たとえば、次は false と評価されます。

boolean test = (new Integer(1) == new Integer(1));
System.out.println(test); // "false"

これらは、他のオブジェクトと同様に単なるオブジェクトです。演算子は==、オブジェクトで使用される場合、それらがまったく同じ Java オブジェクトである場合にのみ true と評価されます (equals()内部を比較するためにオーバーライドできるメソッドとは対照的です)。

于 2013-01-03T00:47:33.563 に答える