Different behavior of int and Integer [duplicate] - java

This question already has answers here:
How do I compare two Integers? [duplicate]
(9 answers)
Closed 7 years ago.
I noticed that the following code returns false
Integer a = 600;
Integer b = 600;
System.err.println(a == b);
but this one
int a = 600;
int b = 600;
System.err.println(a == b);
returns true
can anybody explain?

The most important thing to know is the values up to 128 are cached, and the JVM gives you the same objects,for that the reference comparison works. Above 128 it creates a new instance.
For more info go to javadoc of Integer.valueOf(int) (which is what happens behind the scene)

This behavior is correct, in java == compares object references, it checks to see if the two operands point to the same object (not equivalent objects, the same object).
so your 1st example:
Integer a = 600;
Integer b = 600;
System.err.println(a == b);
you are asking java to tell you if the have the same reference, which is false
in the example 2:
a and b are primitives, and you are asking java to tell you if the have the same value, which is True
Jeff had already an answer for this

Related

Can someone explain the logic to me it seems both are equal [duplicate]

This question already has answers here:
Why is 128==128 false but 127==127 is true when comparing Integer wrappers in Java?
(8 answers)
Closed 5 years ago.
Can someone explain me the logic why a and b are both equal and x and y are not both equal but they have the same value.
Integer a = 40;`// integer a
Integer b =40; // integer b
Integer x = 400; // why x and y are not equal
Integer y = 400; // how is that possible
if (a==b){ //first condition
System.out.println("a=b"); //if true print
}else {
System.out.println("a!=b"); // if not true
}
if(x==y){ // second condition
System.out.println("x=y"); // if true print
}else{
System.out.println("x!y"); // if not true print
}
it is a mistake to compare objects (or really a bad practice) with the ==, for that most of the objects overwrite the compareTo() , and obvious the Intege is not the exception.

i am getting true and false output why? [duplicate]

This question already has answers here:
Weird Integer boxing in Java
(12 answers)
Closed 7 years ago.
I know int range is -2147483648 to +2147483647 but here I'm getting output as true and false. Why? Actually i1 and i2 point to the same object, so output is true. I can understood but i3 and i4 also pointing to same object but I got output as false. Why?
public class MainClass {
public static void main(String[] args) {
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2);
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4);
}
}
the output is
true
false
why output should be like this?
Because you are using Integer object. For Integer object, values in between -128 to 127 are pooled
The problem is the difference between == and equals. == just tests to see if two Integer variables point to the same object, which could be either true or false depending on the implementation of your JVM. equals actually tests to see if they hold the same value. So in this case, you'll want to use equals:
// ...
System.out.println(i1.equals(i2));
// ...
System.out.println(i3.equals(i4));

How Integer object is created? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How != and == operators work on Integers in Java?
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 == i2) is return false. Exactly what it happen how it is checking this condition here?
if i assign lesser than 128 in both i1 and i2 if condition is true. How object is created here, it is comman for all the values or different?
Could someone clarify this scenario.
if i assign lesser than 128 in both i1 and i2 if condition is true
Yes this happens because for that range Java uses flyweight pattern and caches Integer objects so you get backed the cached version and == works
This is possible as Integer objects are immutable and the caching is only for the range [-128,127]

java == for Integer [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Inconsistent behavior on java's ==
Integer wrapper objects share the same instances only within the value 127?
I have found the following == behaviour for Integer objects and I fail to understand it. (I am well aware that one should use equals for such comparisons, but I am studying for OCPJP...)
On short, == works as expected for 1000, but not for 10.
The former fragment of code is:
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2) System.out.println("different objects");
if(i1.equals(i2)) System.out.println("meaningfully equal");
and it behaves as one would expect:
different objects
meaningfully equal
The latter though:
Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4) System.out.println("same object");
if(i3.equals(i4)) System.out.println("meaningfully equal");
has the following output:
same object
meaningfully equal
Can someone please explain why this is happening?
Since Java 5, wrapper class caching was introduced. The following is an examination of the cache created by an inner class, IntegerCache, located in the Integer cache. For example, the following code will create a cache:
Integer myNumber = 10
or
Integer myNumber = Integer.valueOf(10);
256 Integer objects are created in the range of -128 to 127 which are all stored in an Integer array. This caching functionality can be seen by looking at the inner class, IntegerCache, which is found in Integer:
So when creating an object using Integer.valueOf or directly assigning a value to an Integer within the range of -128 to 127 the same object will be returned. Therefore, consider the following example:
Integer i = 100;
Integer p = 100;
if (i == p)
System.out.println("i and p are the same.");
if (i != p)
System.out.println("i and p are different.");
if(i.equals(p))
System.out.println("i and p contain the same value.");
The output is:
i and p are the same.
i and p contain the same value.
It is important to note that object i and p only equate to true because they are the same object, the comparison is not based on the value, it is based on object equality. If Integer i and p are outside the range of -128 or 127 the cache is not used, therefore new objects are created. When doing a comparison for value always use the “.equals” method. It is also important to note that instantiating an Integer does not create this caching.
Remember that “==” is always used for object equality, it has not been overloaded for comparing unboxed values
See Integer wrapper objects share the same instances only within the value 127?. The Integer class keeps shared static instances around for common values.

Why are these == but not `equals()`?

I'm a bit confused about the way Java treats == and equals() when it comes to int, Integer and other types of numbers. For example:
Integer X = 9000;
int x = 9000;
Short Y = 9000;
short y = 9000;
List<Boolean> results = new ArrayList<Boolean>();
// results.add(X == Y); DOES NOT COMPILE 1)
results.add(Y == 9000); // 2)
results.add(X == y); // 3)
results.add(X.equals(x)); // 4)
results.add(X.equals(Y)); // 5)
results.add(X.equals(y)); // 6)
System.out.println(results);
outputs (maybe you should make your guess first):
[true, true, true, false, false]
That X == Y does not compile is to be expected, being different objects.
I'm a little surprised that Y == 9 is true, given that 9 is by default an int, and given that 1) didn't even compile. Note that you can't put an int into a method expecting a Short, yet here they are equal.
This is surprising for the same reason as two, but it seems worse.
Not surprising, as x is autoboxed to and Integer.
Not surprising, as objects in different classes should not be equal().
What?? X == y is true but X.equals(y) is false? Shouldn't == always be stricter than equals()?
I'd appreciate it if anyone can help me make sense of this. For what reason do == and equals() behave this way?
Edit: I have changed 9 to 9000 to show that this behavior is not related to the any unusual ways that the integers from -128 to 127 behave.
2nd Edit: OK, if you think you understand this stuff, you should consider the following, just to make sure:
Integer X = 9000;
Integer Z = 9000;
short y = 9000;
List<Boolean> results = new ArrayList<Boolean>();
results.add(X == Z); // 1)
results.add(X == y); // 2)
results.add(X.equals(Z)); // 3)
results.add(X.equals(y)); // 4)
System.out.println(results);
outputs:
[false, true, true, false]
The reason, as best as I understand it:
Different instance, so different.
X unboxed, then same value, so equal.
Same value, so equal.
y cannot be boxed to an Integer so cannot be equal.
(small) Integer instances are cached, so the invariant x == y is holded for small instances (actually -127 +128, depends on JVM):
Integer a = 10;
Integer b = 10;
assert(a == b); // ok, same instance reused
a = 1024;
b = 1024;
assert(a == b); // fail, not the same instance....
assert(a.equals(b)); // but same _value_
EDIT
4) and 5) yield false because equals check types: X is an Integer whereas Y is a Short. This is the java.lang.Integer#equals method:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
The reason for
X == y
being true has to do with binary numeric promotion. When at least one operand to the equality operator is convertible to a numeric type, the numeric equality operator is used. First, the first operand is unboxed. Then, both operands are converted to int.
While
X.equals(y)
is a normal function call. As has been mentioned, y will be autoboxed to a Short object. Integer.equals always returns false if the argument is not an Integer instance. This can be easily seen by inspecting the implementation.
One could argue that this is a design flaw.
The morale of the story:
Autoboxing/unboxing is confusing, as is type promotion. Together, they make for good riddles but horrendous code.
In practice, it seldom makes sense to use numeric types smaller than int, and I'm almost inclined to configure my eclipse compiler to flag all autoboxing and -unboxing as an error.
Your problem here is not only how it treats == but autoboxing... When you compare Y and 9 you are comparing two primitives that are equal, in the last two cases you get false simply because that's how equals work. Two objects are equal only if they are of the same kind and have the same value.
When you say in "X.equals(y)" you are telling it to do Integer.equals(Short) and looking at the implementation of Integer.equals() it will fail:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Because of autoboxing the last two will result in the same failure as they will both be passed in as Shorts.
Edit: Forgot one thing... In the case of results.add(X == y); it will unbox X and do (X.intValue() == y) which happens to be true as well as 9 == 9
This automatic conversion is called autoboxing.
I remember a good practice for overriding "equal(object obj)" is of first checking the type of the parameter passed in. So perhap this causes X.equals(Y) to be false. You might check the souce code to dig out the truth :)
A bit more detail on how autoboxing works and how "small" valued Integer objects are cached:
When a primitive int is autoboxed into an Integer, the compiler does that by replacing the code with a call to Integer.valueOf(...). So, the following:
Integer a = 10;
is replaced by the compiler with the following:
Integer a = Integer.valueOf(10);
The valueOf(...) method of class Integer maintains a cache that contains Integer objects for all values between -127 and 128. If you call valueOf(...) with a value that's in this range, the method returns a pre-existing object from the cache. If the value is outside the range, it returns a new Integer object initialized with the specified value. (If you want to know exactly how it works, lookup the file src.zip in your JDK installation directory, and look for the source code of class java.lang.Integer in it.)
Now, if you do this:
Integer a = 10;
Integer b = 10;
System.out.println(a == b);
you'll see that true is printed - but not because a and b have the same value, but because a and b are referring to the same Integer object, the object from the cache returned by Integer.valueOf(...).
If you change the values:
Integer a = 200;
Integer b = 200;
System.out.println(a == b);
then false is printed, because 200 is outside the range of the cache, and so a and b refer to two distinct Integer objects.
It's unfortunate that == is used for object equality for value types such as the wrapper classes and String in Java - it's counter-intuitive.
Java will convert an Integer into an int automatically, if needed. Same applies to Short. This feature is called autoboxing and autounboxing. You can read about it here.
It means that when you run the code:
int a = 5;
Integer b = a;
System.out.println(a == b);
Java converts it into:
int a = 5;
Integer b = new Integer(a);
System.out.println(a == b.valueOf());

Categories