I am getting NullPointerException in one instance below while its counterpart runs smooth.
public static void main(String[] args){
System.out.println(withTernary(null, null)); //Null Pointer
System.out.println(withIfElse(null, null)); //No Exception
}
private static Boolean withTernary(String val, Boolean defVal){
return val == null ? defVal : "true".equalsIgnoreCase(val);
}
private static Boolean withIfElse(String val, Boolean defVal){
if (val == null) return defVal;
else return "true".equalsIgnoreCase(val);
}
Online version
Online version with the lines in main
reversed, which outputs null
from withIfElse
and then fails in withTernary
.
I am using following java version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
Moreover, as has been pointed out, at the byte code level there's really no difference between the ternary operator and if-then-else.
Null-safe operator is a new syntax in PHP 8.0, that provides optional chaining feature to PHP. The null-safe operator allows reading the value of property and method return value chaining, where the null-safe operator short-circuits the retrieval if the value is null , without causing any errors.
5.2. The ternary operator is a shortcut expression that is equivalent to an if/else branch assigning some value to a variable. Instead of: if (string!=null && string.
Here's the relevant quote from the spec (§15.25.2):
Boolean conditional expressions are standalone expressions (§15.2).
The type of a boolean conditional expression is determined as follows:
If the second and third operands are both of type
Boolean
, the conditional expression has typeBoolean
.Otherwise, the conditional expression has type
boolean
.
Therefore, the overall expression's type is considered to be boolean
, and the Boolean
value is autounboxed, causing a NullPointerException
.
As mentioned in the comments, why doesn't the following raise an exception?
return val == null ? null : "true".equalsIgnoreCase(val);
Well, the above excerpt from the spec specifically only applies to boolean conditional expressions, which are specified here (§15.25):
If both the second and the third operand expressions are boolean expressions, the conditional expression is a boolean conditional expression.
For the purpose of classifying a conditional, the following expressions are boolean expressions:
An expression of a standalone form (§15.2) that has type
boolean
orBoolean
.A parenthesized
boolean
expression (§15.8.5).A class instance creation expression (§15.9) for class
Boolean
.A method invocation expression (§15.12) for which the chosen most specific method (§15.12.2.5) has return type
boolean
orBoolean
.
(Note that, for a generic method, this is the type before instantiating the method's type arguments.)A
boolean
conditional expression.
Since null
is not a boolean expression, the overall conditional expression is not a boolean conditional expression. Referring to Table 15.2 (later in the same section), we can see that such an expression is considered to have a Boolean
type, so no unboxing occurs, and no exception is raised.
val == null ? defVal : "true".equalsIgnoreCase(val)
- in this expression, the third argument is boolean
, and since the ternary operator must have one static type, it will try to unbox the null
, hence the NPE. Only the assignment to Boolean
will cause boxing again.
Check this.
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