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?
IntegerextendsObjectand therefore==is defined as reference equality, not value equality.When comparing
Integerwithint, theIntegerwill be unboxed to anint, and the two operands will be compared for value equality. (Unless theIntegervalue isnull, in which caseNullPointerExceptionwill be thrown instead.) ButInteger == Integeris never safe.That said, because by default the runtime pre-allocates
Integerinstances for small integers (-128 through 127, according to the OpenJDK source), you can often getInteger == Integerto 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 ofInteger(orString, or anyObject) will compare equal using==, unless you are explicitly looking for reference equality.