2014-10-18 4 views
10

Ich habe einen Teil von Code wie folgt:Warum wirft ein NULL-Wert aus einer ternären Anweisung einer Booleschen Variablen eine NPE zu?

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); 
} 

Wenn defaultValue nicht gleich null ist der Code funktioniert gut, aber wenn defaultValuenull ist die JVM wirft einen NullPointerException. Dieser Code wurde mit jdk 1.6.45 kompiliert.

Warum habe ich diese Ausnahme?

+0

Da in Java ein boolean Wert nicht null sein kann. – Titus

+3

@Titus aber Boolean kann Boolean kann nicht –

+0

Was versuchen Sie in ternary Operator zu tun? –

Antwort

9

Es ist der ternäre Operator. Da die erste Option trueValue.equalsIgnoreCase(fieldValue) ein boolescher Wert ist, scheint es anzunehmen, dass die zweite Option defaultValue ein boolescher Wert ist und kein Nullable . Es ist seltsam, aber das scheint zu sein. Wenn Sie die erste Option, um Boolean werfen, geht der Fehler weg:

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

Java language specification sagt:

Wenn einer der zweiten und dritten Operanden der Urtyp ist T, und die Art des anderen ist das Ergebnis der Anwendung der Box-Konvertierung (§5.1.7) auf T, dann ist der Typ des bedingten Ausdrucks T.

8

Vom JLS: 15.25. Conditional Operator ? :

Wenn einer der zweiten und dritten Operanden der Urtyp ist T, und die Art des anderen ist das Ergebnis Boxen Umwandlung des Anwendens (§5.1.7) zu T , dann ist der Typ des bedingten Ausdrucks T.

Aka: Wenn der 2. und 3. Operand primitive und boxed Referenztyp sind, wird das Ergebnis als primitiver Typ betrachtet. Am Ende Ihrer Operation boxen Sie es erneut, aber bis dahin haben Sie bereits versucht, null einem primitiven Typ zuzuordnen - was nicht möglich ist.

Die Unterzeichnung String#equalsIgnoreCase ist ...

public boolean equalsIgnoreCase 
+2

+1, obwohl "bereits versucht, einem primitiven Typ" null "zuzuweisen, wäre besser geschrieben als" bereits versucht, ** zu leeren ** 'Null' zu einem primitiven Typ "oder vielleicht" bereits implizit als 'booleanValue "() 'auf einer 'Null'-Referenz". – ruakh

Verwandte Themen