问题
The following code seemed really confusing to me since it provided two different outputs.The code was tested on jdk 1.7.
public class NotEq {
public static void main(String[] args) {
ver1();
System.out.println();
ver2();
}
public static void ver1() {
Integer a = 128;
Integer b = 128;
if (a == b) {
System.out.println(\"Equal Object\");
}
if (a != b) {
System.out.println(\"Different objects\");
}
if (a.equals(b)) {
System.out.println(\"Meaningfully equal.\");
}
}
public static void ver2() {
Integer i1 = 127;
Integer i2 = 127;
if (i1 == i2) {
System.out.println(\"Equal Object\");
}
if (i1 != i2){
System.out.println(\"Different objects\");
}
if (i1.equals(i2)){
System.out.println(\"Meaningfully equal\");
}
}
}
Output:
[ver1 output]
Different objects
Meaningfully equal.[ver2 output]
Equal Object
Meaningfully equal
Why the == and != testing produces different results for ver1() and ver2() for same number much less than the Integer.MAX_VALUE? Can it be concluded that == checking for numbers greater than 127 (for wrapper classes like Integer as shown in the code) is totally waste of time?
回答1:
Integers are cached for values between -128 and 127 so Integer i = 127
will always return the same reference. Integer j = 128
will not necessarily do so. You will then need to use equals
to test for equality of the underlying int
.
This is part of the Java Language Specification:
If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
But 2 calls to Integer j = 128
might return the same reference (not guaranteed):
Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.
回答2:
Because small integers are interned in Java, and you tried the numbers on different sides of the "smallness" limit.
回答3:
There exist an Integer object cache from -128 and up to 127 by default. The upper border can be configured. The upper cache border can be controlled by VM option -XX:AutoBoxCacheMax=<size>
You are using this cache when you use the form:
Integer i1 = 127;
or
Integer i1 = Integer.valueOf(127);
But when you use
Integer i1 = new Integer(127);
then you're guaranteed to get a new uncached object. In the latter case both versions print out the same results. Using the cached versions they may differ.
回答4:
https://www.owasp.org/index.php/Java_gotchas
I got this link from one of my professors, pretty informative.
回答5:
Java caches integers from -128 to 127 That is why the objects ARE the same.
回答6:
I think the == and != operators when dealing with primitives will work how you're currently using them, but with objects (Integer vs. int) you'll want to perform testing with .equals() method.
I'm not certain on this, but with objects the == will test if one object is the same object or not, while .equals() will perform testing that those two objects contain equivalence in value (or the method will need to be created/overridden) for custom objects.
来源:https://stackoverflow.com/questions/9824053/how-and-operators-work-on-integers-in-java