2017-01-17 48 views
10

Ten program powinien unikać wartości Null podczas wywoływania w Plugin z wartością null. ale nadal jestem coraz NPE .. Każda pomocNPE przy próbie zwracania wartości null

System.out.println(toFloat(null, null));

private static Float toFloat(Float def, String str) { 
    try { 
     return str != null ? Float.parseFloat(str) : def; 
    } catch (NumberFormatException e) { 
     return def; 
    } 
} 

Odpowiedz

14

To bardzo subtelne. Float.parseFloat zwraca float, a nie Float. Drugie dwa operandy operatora warunkowego muszą być tego samego typu, ale dajesz mu float (wynik) i Float (def). Kompilator wybiera float, ponieważ Float może być wymuszony na float poprzez automatyczne rozpakowywanie.

Więc co wyjścia kompilator jest tak, jakbyś którą napisane tak:

private static Float toFloat(Float def, String str) { 
    try { 
     return str != null ? Float.parseFloat(str) : def.floatValue(); 
     // Note ----------------------------------------^^^^^^^^^^^^^ 
    } catch (NumberFormatException e) { 
     return def; 
    } 
} 

... i oczywiście, nazywając floatValue na null zgłasza NPE.

Można to naprawić, upewniając się, że drugi typ operandu to Float, a nie float. Wiele sposobów, aby to zrobić, ale jak Zefick points out, najprostszym jest Float.valueOf(String):

private static Float toFloat(Float def, String str) { 
    try { 
     return str != null ? Float.valueOf(str) : def; 
    } catch (NumberFormatException e) { 
     return def; 
    } 
} 
+2

Float.valueOf (str) – Zefick

+0

@Zefick: Doh! Tak, rzeczywiście ... –

+2

Moja sugestia, dla zachowania przejrzystości, polegałaby na pozbyciu się operatora '?' I użycie prostego 'if'. Tak, masz jeszcze kilka linii kodu. Ale łatwiej byłoby zrozumieć, co się dzieje, podczas gdy parsowanie i natychmiastowy powrót do pływaka kapitału sprawiłoby, że pomyślałem "co do cholery robiłem wtedy ..." kilka miesięcy później ... :) Cóż, wartość 'valueOf' jest najprostszym sposobem oczywiście ... Duh! – Quota