简体   繁体   English

整数枚举和拆箱

[英]Integer Enum and Unboxing

public class Document{
    private Integer status;

    // get()/set()
}

Then an enum: 然后是一个枚举:

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;
        }
    }

In a method I'm using the above method as below: 在一种方法中,我使用上述方法,如下所示:

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

I get true here. 我在这里是真的。 Looks alright. 看起来不错。 In the same method, After couple of lines, I do this: 在相同的方法中,经过两行之后,我这样做:

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

}

I get a false. 我弄错了。 I researched and found something about caching and boxing features in Java. 我研究并发现了有关Java中的缓存和装箱功能的信息。 I converted the enum definition as this: 我将枚举定义转换为:

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;
    }
}

Now, no issues. 现在,没有问题。 I get true in both cases. 在两种情况下我都是正确的。

Question is why this happening? 问题是为什么会这样? I feel this behaviour is extremely unstable. 我觉得这种行为非常不稳定。 It's a large application I'm dealing with and I'm using Integer == Integer comparison every where. 我正在处理的是一个大型应用程序,并且在任何地方都使用Integer == Integer比较。 Am I safe here? 我在这里安全吗?

Integer extends Object and therefore == is defined as reference equality, not value equality. Integer扩展了Object ,因此==被定义为引用相等,而不是值相等。

When comparing Integer with int , the Integer will be unboxed to an int , and the two operands will be compared for value equality. Integerint比较时,会将Integer拆箱为int ,并将比较两个操作数的值是否相等。 (Unless the Integer value is null , in which case NullPointerException will be thrown instead.) But Integer == Integer is never safe. (除非Integer值为null ,否则将抛出NullPointerException 。)但是Integer == Integer永远都不安全。

That said, because by default the runtime pre-allocates Integer instances for small integers (-128 through 127, according to the OpenJDK source ), you can often get Integer == Integer to work for small values. 就是说,因为默认情况下,运行时会为小整数预分配Integer实例(根据OpenJDK源 ,从-128到127),所以您通常可以使Integer == Integer用于较小的值。 But that behavior does not hold for larger values, and it is never required to hold. 但是该行为并不适用于较大的值,也不需要保留。 So you should never assume that two instances of Integer (or String , or any Object ) will compare equal using == , unless you are explicitly looking for reference equality. 因此,除非您明确寻找引用相等性,否则您永远不要假定两个Integer实例(或String或任何Object )将使用==比较相等。

You should use int instead of Integer , unless you need to handle null values. 除非需要处理空值,否则应使用int而不是Integer

There are indeed issues with comparing Integer objects. 比较Integer对象确实存在问题。 For example, the following will evaluate to false: 例如,以下内容将评估为false:

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

These are just objects like any other. 这些就像其他任何对象一样。 The == operator, when used with objects, only evaluates to true if they are the exact same Java object (as opposed to the equals() method, which can be overridden to compare the internals). ==运算符与对象一起使用时,仅当它们是完全相同的Java对象时才计算为true(与equals()方法相对,后者可以重写以比较内部)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM