Clearly returning null for a boolean type is an error. Why doesn't javac catch this?
public class Test {
public static void main(String[] args) {
Object a = null;
System.out.println(getThing(a));
}
private static boolean getThing(Object o) {
return o == null ? null : Boolean.TRUE;
}
}
Clearly returning null for a boolean type is an error. Why doesn't javac catch this?
Given that question, here's the relevant part of the code:
private static boolean getThing(Object o) {
return o == null ? null : Boolean.TRUE;
}
That method includes a conditional expression (JLS 15.25) where:
o == null
null
Boolean.TRUE
The reason javac
allows it is:
The conditional expression is classified as a reference conditional expression (JLS 15.25.3) due to the second and third expressions "null" and "Boolean.TRUE", excerpted from JLS 15.25:
If both the second and the third operand expressions are boolean expressions, the conditional expression is a boolean conditional expression.
If both the second and the third operand expressions are numeric expressions, the conditional expression is a numeric conditional expression.
Otherwise, the conditional expression is a reference conditional expression.
The entire conditional expression is classified as type java.lang.Boolean
The conditional expression is of reference type Boolean
, and the method return type – primitive "boolean" – can be unboxed from Boolean
The compiler kind of "allowing" a code path where "null" might be unboxed to "boolean" isn't all that different from various other obvious programming errors.
For example, here's code that creates a new object, gives it a value of null
, then tries
to invoke a method on that object.
This code compiles fine but, unsurprisingly, throws an exception at runtime:
Object o = null;
System.out.println(o.hashCode());
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "Object.hashCode()" because "o" is null
Though your code compiles, the following exception is thrown at runtime when null
is unboxed to boolean:
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "java.lang.Boolean.booleanValue()"
While the return value of the statement is null
– a valid value for Boolean
– unboxing to
a boolean primitive (to line up with the method return type) throws an exception. Unboxing tries to call null.booleanValue()
which won't work.
You weren't asking, but – an easy fix would be
to change the return type of the method from primitive boolean
to Boolean
.
After doing that, your program compiles and runs, printing "null" (from System.out.println(getThing(a))
.