整数枚举和拆箱

Fir*_*mir 1 java

public class Document{
    private Integer status;

    // get()/set()
}
Run Code Online (Sandbox Code Playgroud)

然后是一个枚举:

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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在一个方法我使用上面的方法如下:

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

我在这里说实话.看起来不错.在同样的方法中,经过几行,我这样做:

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

}
Run Code Online (Sandbox Code Playgroud)

我弄错了.我研究并发现了一些关于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,没有问题.我在两种情况下都是如此.

问题是为什么会发生这种情况?我觉得这种行为非常不稳定.这是我正在处理的一个大型应用程序,我在Integer == Integer每个地方使用比较.我在这里安全吗?

Dan*_*den 6

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

Integer与之比较时int,Integer将取消装箱到a int,并将比较两个操作数的值相等性.(除非是Integernull,否则NullPointerException将被抛出.)但Integer == Integer绝不安全.

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