整数枚举和拆箱

时间:2013-01-03 00:39:56

标签: java

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比较。我在这里安全吗?

2 个答案:

答案 0 :(得分:6)

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

Integerint进行比较时,Integer将被取消装箱到int,并且将比较两个操作数的值相等性。 (除非Integer值为null,否则将引发NullPointerException。但Integer == Integer永远不会安全。

那就是说,因为默认情况下运行时为小整数预先分配Integer个实例(-128到127,根据the OpenJDK source),你经常可以让Integer == Integer工作小的价值观。但是这种行为不适用于较大的值,并且永远不需要保持。因此,除非您明确寻找引用相等,否则不应假设Integer(或String或任何Object)的两个实例将使用==进行比较。 / p>

答案 1 :(得分:3)

您应该使用int而不是Integer,除非您需要处理空值。

比较Integer对象确实存在问题。例如,以下内容将评估为false:

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

这些只是与其他对象一样的对象。 ==运算符与对象一起使用时,如果它们是完全相同的Java对象,则仅计算结果为true(与equals()方法相反,可以重写该方法以比较内部结构)。