public static void main(String[] args) {
System.out.println((Integer.valueOf("5000") <= Integer.valueOf("5000")));
System.out.println((Integer.valueOf("5000") == Integer.valueOf("5000")));
}
The above code prints true
and false
respectively. This is understandable, but why it prints false
when we use ==
.
But, when using <=
(less than or equal to) why is the answer true
?
Using == operator in Java to compare wrapper objects.
Long is a wrapper class for the primitive type long. Since they are objects and not primitive values, we need to compare the content of Long instances using . equals() instead of the reference comparison operator (==).
When a wrapper is compared with a primitive using ==, the wrapper is unwrapped. That's true! But which method is invoked/called depends on the type of the wrapper. If your wrapper is of type Integer, then indeed the intValue method will be called.
Comparing Integers Integer is a wrapper class of int, and it provides several methods and variables you can use in your code to work with integer variables. One of the methods is the compareTo() method. It is used to compare two integer values. It will return a -1, 0, or 1, depending on the result of the comparison.
To explain why the code prints such output, we might need to look into lower level:
I decompiled your code to bytecode level.
System.out.println((Integer.valueOf("5000") <= Integer.valueOf("5000")));
The bytecode is(useless information is removed):
LDC "5000"
INVOKESTATIC java/lang/Integer.valueOf (Ljava/lang/String;)Ljava/lang/Integer;
INVOKEVIRTUAL java/lang/Integer.intValue ()I
LDC "5000"
INVOKESTATIC java/lang/Integer.valueOf (Ljava/lang/String;)Ljava/lang/Integer;
INVOKEVIRTUAL java/lang/Integer.intValue ()I
IF_ICMPGT L1
You can see for the left part of <=
, JVM use Integer.valueOf function to convert the string to a Integer object. Then use Integer.intValue function to extract the inner value of this object(also called auto-unboxing). So, for the left part, we get an int
value.
The right part of <=
is the same as left part.
The last line IF_ICMPGT
, is to compare these two int values. So, the conclusion is if you are using <=
, Java compiler will do auto-unboxing for you and compare the inner int values.
System.out.println((Integer.valueOf("5000") == Integer.valueOf("5000")));
The bytecode is(useless information is removed):
LDC "5000"
INVOKESTATIC java/lang/Integer.valueOf (Ljava/lang/String;)Ljava/lang/Integer;
LDC "5000"
INVOKESTATIC java/lang/Integer.valueOf (Ljava/lang/String;)Ljava/lang/Integer;
IF_ACMPNE L4
You can see the bytecode is different from the 1st line. It just convert string to Integer objects, but NOT auto-unboxing them. And because they are two individual objects, they must have different addresses(In the memory).
The last line IF_ACMPNE
is going to compare the addresses of these two Integer objects. So, the conclusion is if you are using ==
, Java compiler will do NOTauto-unboxing for you and compare the object addresses.
The Integer
class caches the Integer objects for range -128~127. It means if you pass a string with in this range, you will get the exactly same Integer object. Below code will print true:
System.out.println((Integer.valueOf("127") == Integer.valueOf("127"))); // true
When you compare wrapper classes using <=
, >=
Java performs unboxing and compares actual int (or double, long, etc) values between each other. So Integer.valueOf("5000") <= Integer.valueOf("5000")
will work like this Integer.valueOf("5000").intValue() <= Integer.valueOf("5000").intValue()
which is equivalent to 5000 <= 5000
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With