Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why ternary operation gives nullpointer while its ifelse counterpart doesn't? [duplicate]

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)
like image 289
DKSRathore Avatar asked Sep 19 '14 07:09

DKSRathore


People also ask

Which is faster ternary operator or if else?

Moreover, as has been pointed out, at the byte code level there's really no difference between the ternary operator and if-then-else.

What is nullsafe?

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.

What is ternary operator in groovy?

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.


2 Answers

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 type Boolean.

  • 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 or Boolean.

  • 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 or Boolean.
    (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.

like image 128
Alexis King Avatar answered Oct 29 '22 10:10

Alexis King


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.

like image 32
sfThomas Avatar answered Oct 29 '22 11:10

sfThomas