I was writing a simple condition
List<Long> path = doSomething(); // returns a list of Long and all equal to -1
if (path.get(0)==-1)
sysout("first condition works"); // never executes
if (path.get(0).equals(-1))
sysout("sec condition works"); //never executes
if (path.get(0).equals(new Long(-1)))
sysout("third condition works"); //works!
Why is that? Please point me to some article in the official doc files to read more!
Integer Long ^ ^ | | auto-boxing/auto-unboxing | | v v int -----------------------> long primitive promotion
This schema shows what implicit conversions Java can do between different things.
In Java, objects and primitives are unfortunately different beasts: Long
and long
are not the same things. An implicit conversion from long
to Long
is called auto-boxing . An implicit conversion from Long
to long
is called auto-unboxing . This kind of conversion is descibed in section 5.1.8 of the Java Language Specification .
Also, like many other languages, Java has implicit conversions between numeric types. An int
is implicitly promoted to a long
if it is used in an expression that contains other long
s. The contexts in which these promotions can occur are described in section 5.6 of the Java Language Specification .
Note that the literal 1
in Java has type int
. The litteral 1L
has type long
.
Long v = ...
if(v == -1) ...
v
is a Long
and -1
is an int
. Java does not know how to compare objects and primitives: it relies on its implicits conversions rules to do so. Here, -1
is converted (auto-boxed) to an Integer
. So, we are comparing the reference of two objects that don't even have the same type: the test fails.
Long v = ...
if(v.equals(-1)) ...
This is the same thing as above, except that it's not a comparision that triggers the implicit conversion, but a method call. equals
takes an Object
as a parameter, so -1
is converted (auto-boxed) to an Integer
. Implicit conversions triggered by method calls are described in section 5.3 of the Java Language Specification .
Long v = ...
if(v.equals(new Long(-1))) ...
Here, we call the Long.equal
method with a Long
as a parameter, so the test succeeds.
What comparision works, then ?
Long v = ...
if(v.equals(-1L)) ...
-1L
is a long
. It is passed to a method that expects an Object
, so it is implicitly converted (auto-boxed) to a Long
. The test succeeds.
Long v = ...
if(v.longValue() == -1) ...
v.longValue()
is a long
, -1
is an int
. -1
is promoted to a long
because of the ==
operator. The test succeeds.
if (path.get(0)!=null && path.get(0).longValue()==-1)
System.out.println("first condition works");
If you compare long
primitives you can use method longValue() .
However you should check Long
object for null
before calling this method.
Your two first cases are comparing a Long to an Integer (due to autoboxing), and they can never be the same object (naturally).
Your final case is the correct one. Use equals() when comparing objects.
EDIT: Or the longValue()/intValue() etc. methods if you want to use the == operator.
Replace if (path.get(0).equals(-1))
with
if (path.get(0).equals(-1L))
By default, number is treated as Integer in java, and thus the comparison fails.
Take a look at auto-boxing in java for better understanding
Because, equals()
expects Object
. You can't pass premitive value in equals()
method. So, equals(-1)
is incorrect.
Use
if (path.get(0).equals(-1)) //long value
Or
if (path.get(0).longValue()==-1)
Or
if (path.get(0)==-1L)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.