Conversion from null to int possible?
I know that when I read the answer to this I will see that I have overlooked something that was under my eyes. But I have spent the last 30 minutes trying to figure it out myself with no result.
So, I was writing a program in Java 6 and discovered some (for me) strange feature. In order to try and isolate it, I have made two small examples. I first tried the following method:
private static int foo()
{
return null;
}
and the compiler refused it: Type mismatch: cannot convert from null to int.
This is fine with me and it respects the Java semantics I am familiar with. Then I tried the following:
private static Integer foo(int x)
{
if (x < 0)
{
return null;
}
else
{
return new Integer(x);
}
}
private static int bar(int x)
{
Integer y = foo(x);
return y == null ? null : y.intValue();
}
private static void runTest()
{
for (int index = 2; index > -2; index--)
{
System.out.println("bar(" + index + ") = " + bar(index));
}
}
This compiles with no errors! But, in my opinion, there should be a type conversion error in the line
return y == null ? null : y.intValue();
If I run the program I get the following output:
bar(2) = 2
bar(1) = 1
bar(0) = 0
Exception in thread "main" java.lang.NullPointerException
at Test.bar(Test.java:23)
at Test.runTest(Test.java:30)
at Test.main(Test.java:36)
Can you explain this behaviour?
Update
Thank you very much for the many clarifying answers. I was a bit worried because this example did not correspond to my intuition. One thing that disturbed me was that a null was being converted to an int and I was wondering what the result would be: 0 like in C++? That would hae been very strange. Good that the conversion is not possible at runtime (null pointer exception).
Let's look at the line:
return y == null ? null : y.intValue();
In a ? :
statement, both sides of the :
must have the same type. In this case, Java is going to make it have the type Integer
. An Integer
can be null
, so the left side is ok. The expression y.intValue()
is of type int
, but Java is going to auto-box this to Integer
(note, you could just as well have written y
which would have saved you this autobox).
Now, the result has to be unboxed again to int
, because the return type of the method is int
. If you unbox an Integer
that is null
, you get a NullPointerException
.
Note: Paragraph 15.25 of the Java Language Specification explains the exact rules for type conversions with regard to the ? :
conditional operator.
Guava has a pretty elegant solution for this using MoreObjects.firstNonNull
:
Integer someNullInt = null;
int myInt = MoreObjects.firstNonNull(someNullInt, 0);