[英]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. 将Integer
与int
比较时,会将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.