java - 整数枚举和拆箱

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

最佳答案

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

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

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

关于java - 整数枚举和拆箱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14131495/

相关文章:

java - 出界了。无缘无故地尝试访问索引 98

java - 在 Scala 中将 java 对象转换为 Object[]

java - 对使用 kstream 连接的 kafka 拓扑进行单元测试

java - 我可以在其方法内将对象(指匿名内部类)设置为 "null"吗?

java - 实现一个 Map,其中键是一组不重叠的范围

java - 客户端套接字上的 setSoTimeout 不会影响套接字

java - maven构建时如何阻止从其他存储库下载metadata.xml

java - 修复符号构建中 Retrofit 中的 @Body 参数加密?

java - 使用Spring Boot时如何使用SpringTemplateEngine

java - 在 spring bean 中注入(inject) 2D int 数组