2015-06-12 14 views
5

Mój projekt ma kod tak:Chaining Null-Safe Operator

params.stringValue?.trim().replaceAll('aa', 'a') 

Spodziewaliśmy się, że jeśli params.stringValue była zerowa, że ​​zarównotrim() i replaceAll() nie można nazwać.

Jednak otrzymywaliśmy w tej linii NullPointerException, że replaceAll() nie może zostać wywołane na NULL Object.

Musieliśmy zmienić kod, aby być tak:

params.stringValue?.trim()?.replaceAll('aa', 'a') 

Dlaczego pierwszy fragment kodu powyżej nie działa? Czy jest to błąd w Groovy, który kontynuuje ocenę wyrażenia po napotkaniu zerowej wartości?

+0

Myślę, że jest to "funkcja", a nie błąd (!) – Armand

Odpowiedz

4

Jest to droga Groovy działa, rzeczywiście, i został ugryziony others:?.

println książki .author .firstName .trim() concat ("jest wielki").

...

Patrząc na tę linię kodu, pomyślałem na pewno, że jestem bezpieczny przed jakimkolwiek podstępnym Wyjątkiem NullPointerException. Jeśli książka, autor lub firstName mają wartość null, kończę drukować wartość null i nie muszę się martwić o metodę concat(). W końcu, jeśli metoda trim() się powiedzie, nie ma sensu ochrona jej wyniku dla wartości null. I tam właśnie się myliłem.

Nie

były przynajmniej this discussion to zmienić?

.b.c // Czy widzisz błąd? ;)

Otrzymam wyjątek NullPointerException. Mam na myśli, jeśli używasz wartości zerowej? operator w łańcuchowym wyrażeniu, musisz użyć we wszystkich właściwościach, ponieważ jeśli zapomnisz gdzieś umieścić, również otrzymasz błąd. Będzie to miłe, jeśli Groovy będzie w stanie wykryć?. operator w wyrażeniu i wtryskuje go w inne właściwości, jeśli zauważy brak operatora. Tak więc, jeśli wpiszesz ten kod, a2. ? .n "F" własność .befg

Groovy mogłyby naprawić z prawdziwym zerowej bezpieczny wypowiedzi jak ta:???

.b .e .f .g

8

Nie sądzę, aby twoje założenie było prawidłowe.to:

params.stringValue?.trim().replaceAll('aa', 'a') 

nie znaczy:

if(params.stringValue is null) 
    dont proceed to trim() and replaceAll() 

To raczej oznacza:

if(params.stringValue is null) 
    skip trim() without complain but pass null to replaceAll() 

więc trzeba powiedzieć:

params.stringValue?.trim()?.replaceAll('aa', 'a') 

ten pomija zarówno trim() i replaceAll(), jeśli argument przychodzący ma wartość null.

8

Twoje założenie jest tylko częściowo poprawne.

? -operator nie łamie wykonanie w przypadku null, to bloki nazywając obecną metodę i zwraca null zamiast, dlatego trzeba także chronić prawą stronę łańcucha z ?