Java question about autoboxing and object equality / identity [duplicate]
public class Main {
/**
* @param args the command line arguments */
public static void main(String[] args) {
// TODO code application logic here
int a1 = 1000, a2 = 1000;
System.out.print开发者_StackOverflowln(a1==a2);//=>true
Integer b1 = 1000, b2 = 1000;
System.out.println(b1 == b2);//=>false
Integer c1 = 100, c2 = 100;
System.out.println(c1 == c2);//=>true
}
}
Why is b1 == b2
false and c1 == c2
true?
Read this.
Java uses a pool for Integer
s in the range from -128 to 127.
That means if you create an Integer
with Integer i = 42;
and its value is between -128 and 128, no new object is created but the corresponding one from the pool is returned. That is why c1
is indeed identical to c2
.
(I assume you know that ==
compares references, not values, when applied to objects).
The correct answers have already been given. But just to add my two cents:
Integer b1 = 1000, b2 = 1000;
This is awful code. Objects should be initialized as Objects through constructors or factory methods. E.g.
// let java decide if a new object must be created or one is taken from the pool
Integer b1 = Integer.valueOf(1000);
or
// always use a new object
Integer b2 = new Integer(1000);
This code
Integer b1 = 1000, b2 = 1000;
on the other hand implies that Integer was a primitive, which it is not. Actually what you are seeing is a shortcut for
Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000);
and Integer only pools objects from -127 to 127, so it will create two new Objects in this case. So although 1000 = 1000, b1 != b2. This is the main reason why I hate auto-boxing.
Because Integer is for a few low numbers like enumeration so there is always same instance. But higher numbers creates new instances of Integer and operator == compares their references
You can find the answer here:
Strangest language feature in the 6th answer.
Edit: sorry not exatly the answer. The point is that == compares references, not values when you use it with Integer. But with int "==" means equals.
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
Because of this you true in one case, and false in other!
The answer you want is here
If autounboxing had worked also when doing equality checking with the '==' operator you could write:
Long notNullSafeLong1 = new Long(11L)
Long notNullSafeLong2 = new Long(22L)
if ( notNullSafeLong1 == notNullSafeLong2) {
do suff
This would require implementing an override for == so that null==someLong is false and the special case Null==Null is true. Instead we have to use equal() and test for null
Long notNullSafeLong1 = new Long(11L)
Long notNullSafeLong2 = new Long(22L)
if ( (notNullSafeLong1 == null && notNullSafeLong2 == null) ||
(notNullSafeLong1 != null && notNullSafeLong2 != null &
notNullSafeLong1.equals(notNullSafeLong2)) {
do suff
This is alittle more verbose than the first example - if autounboxing had worked for the '==' operator.
精彩评论