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

Integer扩展Object,因此==被定义为引用相等,而不是值相等。

与比较IntegerintInteger将拆箱为int,并且将比较两个操作数的值是否相等。(除非Integer值是null,在这种情况下NullPointerException将被抛出。)但Integer == Integer绝不是安全的。

Integer也就是说,因为默认情况下运行时会为小整数(根据OpenJDK 源代码为 -128 到 127)预分配实例,所以您通常可以Integer == Integer为小值工作。但是这种行为不适用于较大的值,并且永远不需要保持。所以你永远不应该假设Integer(或String,或任何Object)的两个实例将使用 比较相等==,除非你明确地寻找引用相等。

于 2013-01-03T00:46:43.043 回答
3

你应该使用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 回答