2015-06-12 3 views
5

Мой проект имеет код вроде следующего:Chaining Null-Safe Operator

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

Мы ожидали, что если params.stringValue был нулевым, что какtrim() и replaceAll() бы не назвать.

Однако мы получали NullPointerException в этой строке, говоря, что replaceAll() не может быть вызван нулевым объектом.

Нам пришлось изменить код, чтобы быть похожим на это:

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

Почему первый фрагмент кода выше, не работает? Является ли это ошибкой в ​​Groovy, что она продолжает оценивать выражение после того, как однажды был встречен null?

+0

Я думаю, что это «особенность», а не ошибка (!) – Armand

ответ

4

Это путь Groovy работает, на самом деле, и укусил others?:?.

Println книга .author .firstName .trim() CONCAT ("отлично").

...

Глядя на эту строку кода, я уверен, что я был в безопасности от любого скрытого исключения NullPointerException. Если книга, автор или firstName имеют значение null, я просто закончу печать null и не буду беспокоиться о методе concat(). В конце концов, если метод trim() преуспевает, нет смысла защищать его результат за нуль. И вот где я был неправ.

Там было по крайней мере this discussion изменить, что:

.b.c // Вы видите ошибку? ;)

Я получу исключение NullPointerException. Я имею в виду, если вы используете нуль-сейф?. оператор в цепном выражении, , вы должны использовать его во всех свойствах, потому что, если вы забудете что-то встать, вы также получите сообщение об ошибке. Это будет быть хорошим, если Groovy может обнаружить?. оператор в выражении, и он вводит его в другие свойства, если видит, что оператор отсутствует. Итак, если вы наберете это

a? .b? .e.f? .g // Я забыл поставить?. ? .n "F" свойство .befg

Groovy может исправить это с реальным нулем безопасным выражением, как это:??

.b .e .f .g

8

Я не думаю, что ваше предположение было правильным.это:

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

не означает:

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

Это скорее означает:

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

так что вы должны сказать:

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

Это будет пропускать как trim() и replaceAll(), если входящий аргумент равен NULL.

8

Ваше предположение является лишь частично правильным.

? -оператором не прерывать выполнение в случае нулевой, он блокирует созывающие текущий метод, и возвращает null вместо этого, поэтому необходимо также защитить правую цепи с ?