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
比较。我在这里安全吗?
答案 0 :(得分:6)
Integer
扩展Object
,因此==
被定义为引用相等,而不是值相等。
将Integer
与int
进行比较时,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()
方法相反,可以重写该方法以比较内部结构)。