Reputation: 1303
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. 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. Am I safe here?
Upvotes: 1
Views: 932
Reputation: 60997
Integer
extends Object
and therefore ==
is defined as reference equality, not value equality.
When comparing Integer
with int
, the Integer
will be unboxed to an int
, and the two operands will be compared for value equality. (Unless the Integer
value is null
, in which case NullPointerException
will be thrown instead.) But Integer == Integer
is never safe.
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. 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.
Upvotes: 6
Reputation: 33572
You should use int
instead of Integer
, unless you need to handle null values.
There are indeed issues with comparing Integer
objects. For example, the following will evaluate to 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).
Upvotes: 3