Why does assigning a null value from a ternary sta

2020-07-05 06:26发布

问题:

I have a part of code like this:

public static void main(String[] args) throws Exception {
    String trueValue = Boolean.TRUE.toString();
    String fieldValue = null;
    Boolean defaultValue = null;

    Boolean value = (fieldValue != null ? trueValue.equalsIgnoreCase(fieldValue) : defaultValue);

    System.out.println(value);
}

When defaultValue is not equal to null the code works fine, but when defaultValue is null the JVM throws a NullPointerException. This code was compiled using jdk 1.6.45.

Why did I get this exception?

回答1:

Java language specification says:

If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.



回答2:

It's the ternary operator. Because the first option trueValue.equalsIgnoreCase(fieldValue) is a boolean, it seems to assume the second option defaultValue is a boolean rather than a nullable Boolean. It's odd, but that seems to be what's happening. If you cast the first option to Boolean, the error goes away:

Boolean value = (fieldValue != null ? (Boolean) trueValue.equalsIgnoreCase(fieldValue) : defaultValue);


回答3:

From the JLS: 15.25. Conditional Operator ? :

If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

Aka: when the 2nd and 3rd operand are primitive and boxed reference type, the result is considered the primitive type. At the end of your operation you are boxing it again, but by then you have already tried to assign null to a primitive type - which isn't possible.

The signature of String#equalsIgnoreCase is...

public boolean equalsIgnoreCase