2014-10-18 17 views
10

mam część kodu:Dlaczego przypisanie wartości pustej z trójskładnikowej instrukcji do zmiennej Boolean powoduje wyświetlenie NPE?

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

Kiedy defaultValue nie jest równa null kod działa poprawnie, ale kiedy defaultValue jest null JVM rzuca NullPointerException. Ten kod został skompilowany przy użyciu jdk 1.6.45.

Dlaczego otrzymałem ten wyjątek?

+0

Ponieważ w Javie wartość logiczna nie może być null. – Titus

+3

@ Titus ale Boolean może boolean nie może –

+0

co próbujesz zrobić w Ternary Operator? –

Odpowiedz

9

To jest operator trójskładnikowy. Ponieważ pierwsza opcja trueValue.equalsIgnoreCase(fieldValue) ma wartość boolowską, wydaje się, że druga opcja to defaultValue, która jest wartością boolowską, a nie nullową Boolean. To dziwne, ale wydaje się, że to się dzieje. Jeśli pierwszy rzuci opcję Boolean, błąd odchodzi:

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

Java language specification mówi:

jeśli jeden z drugim i trzecim operandów jest prymitywnego typu T i typu drugiego jest wynikiem zastosowania konwersji bokserskiej (§5.1.7) do T, wówczas typem wyrażenia warunkowego jest T.

8

Z JLS: 15.25. Conditional Operator ? :

Jeśli jeden z drugim i trzecim operandów jest prymitywnego typu T i typu drugiego jest wynikiem stosowania konwersji boks (§5.1.7) do T , a następnie typem warunkowego wyrażenia jest T.

Aka: gdy 2 i 3 operand są prymitywne i box rodzaj odniesienia, wynik jest uważany za prymitywny typ. Pod koniec swojej operacji znów ją boksujesz, ale już wtedy próbowałeś przypisać null do typu pierwotnego - co nie jest możliwe.

Podpis String#equalsIgnoreCase jest ...

public boolean equalsIgnoreCase 
+2

+1, chociaż "już próbowałeś przypisać' null' do typu pierwotnego "byłoby lepiej napisane jako" już próbowałem ** rozpakować ** 'null' do typu pierwotnego", lub być może jako "już niejawnie nazwane' booleanValue() 'na odwołaniu' null' ". – ruakh