Ternary Operator needs to find out the most appropriate return type for both operands.
Thus, it allows some "polish" of the return type.
As showed in your first code snippet:
public static boolean isNullOrEmpty(String s)
{
return s != null ? s.isEmpty() : null;
}
s.empty()
returns primitive boolean
whereas third operand returns null
.
So the most specific common return type is Boolean
. Compiler job is like replace the line by:
return s != null ? s.isEmpty() : (Boolean)null;
Return type method expects a boolean
primitive, so the compiler says: "cool, I just have to unbox my result !". Unfortunately, null
isn't unboxable and leads to an ugly NPE.
With your second snippet:
public static boolean isNullOrEmpty(String s)
{
if(s != null)
return s.isEmpty();
else
return null;
}
No additional "polish" of pre-return type is made since compiler doesn't link both return statements in this code => might be a too hard job for it.
So, in this case, it is logical that the code doesn't even compile since null
is NOT associated to Boolean
! So, no kind of cast occurs.
To compile it, it should be written as:
public static boolean isNullOrEmpty(String s)
{
if(s != null)
return s.isEmpty();
else
return (Boolean)null;
}
But does not prevent the famous NPE to occur while attempting to unbox ;)