StringUtils vs! = Null - PullRequest
       1

StringUtils vs! = Null

0 голосов
/ 10 сентября 2018

Я часто сталкиваюсь с очень разными валидациями String, и мы все знаем, что есть новые библиотеки, такие как StringUtils. Может кто-нибудь объяснить, почему, например, StringUtils.isNotBlank(paymentTerm) более или менее предпочтительнее, чем paymentTerm != null?

Ответы [ 3 ]

0 голосов
/ 10 сентября 2018

paymentTerm != null и StringUtils.isNotBlank(paymentTerm) не выполняют одно и то же.
Если вы хотите только проверить ненулевое значение объекта String, вы не хотите использовать isNotBlank(), но использовать != null. Так что может все же иметь смысл использовать != null.
Обратите внимание, что в качестве альтернативы вы также можете использовать Object.nonNull(Object), но это часто более многословно (но в справочнике по методам, где это имеет смысл: Object::nonNull).

После того, как мы должны проверить != "", != trimmed "" или просто != null, это вопрос требований.
Даже если isNotBlank() включает в себя != null, вы будете использовать его только в том случае, если требуется , поскольку выполнение большего количества проверок, вводящих в заблуждение код


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

1) Вы хотите проверить размер String длины.

if (myString != null && myString.length() == 8)

это то, что вам нужно.
Выполнение этого с isNotBlank() является многословным и передает две очень специфические вещи (не пустые и минимальной длины), в то время как только последнее имеет значение.

if (StringUtils.isNotBlank(myString) && myString.length() == 8)

2) Вы хотите проверить, что String содержит некоторые символы.

if (myString != null && myString.contains("word"))

все еще то, что вам нужно.

if (String.isNotBlank(myString) && myString.contains("word"))  

Выполнение этого с isNotBlank() выглядит как шум.

3) Вы хотите проверить String равным другому, которое не может быть null или является константным выражением времени компиляции.

Вы хотите прямо написать:

if ("word".equals(myString))

4) Итак, когда вы хотите использовать isNotBlank()?
Только когда вам нужно убедиться, что String не равен нулю и не содержит только пробелы (" ") символов.

if (StringUtils.isNotBlank("word"))
0 голосов
/ 10 сентября 2018

Ваш вопрос действителен, но вы можете быть более вежливым в том, как вы его задаете.

Ответ, это зависит. StringUtils предлагает много хороших методов. isNotBlank () проверяет наличие пустых, пустых и одного или нескольких пробелов и сохраняет определенное количество ручной проверки. Это также может упростить модульное тестирование. С другой стороны, ваш магазин может не захотеть импортировать и полагаться на внешнюю библиотеку.

Как правило, правильный путь, особенно когда вы начинаете, такой же. Вежливо спросите у технического лидера их мнение и согласитесь с ним.

0 голосов
/ 10 сентября 2018

Я чувствую, что предпосылка этого вопроса уже неверна. Вам не нужно проверять наличие нулевых строк в большинстве мест - на самом деле, я бы сказал, что вам следует избегать использования null, когда это возможно, но , особенно , когда существует другое ненулевое значение часового значения. И String уже имеет очень хорошее «пустое» значение: пустая строка ("")!

Если "" и " " нужно сложить в одно и то же значение, то в стандартной библиотеке для этого уже есть совершенно хороший метод: .trim(). Однако .trim(), будучи методом экземпляра в String, работает только со ненулевыми строками. Это не обязательно плохо!

Если null и "" означают разные вещи для вас, то я бы сказал, что ваша модель данных слишком сложна, и вы должны использовать какой-то другой класс-оболочку, а не String непосредственно. Если null и "" означают одно и то же, то вы должны выбрать одно или другое и использовать его последовательно. Это может означать необходимость нескольких != null проверок, но если вам понадобится вспомогательная функция isNullOrEmpty или isNotBlank часто по всей вашей кодовой базе, я бы сказал, что это запах кода, и вы на самом деле следует работать над исправлением проблем модели данных, а не беспокоиться о крошечной вспомогательной функции.

Что это значит? В вопросе Избегание != null операторов ответ с верхним голосом указывает, что на самом деле существует только два типа случаев, когда значение может быть нулевым: либо (1) нулевое является допустимым значением, либо ( 2) значение NULL не является допустимым.

Случай (2) не очень интересен. Нуль не является допустимым значением, поэтому мы не должны пытаться иметь дело с этим. Если что-нибудь, мы просто бросаем исключение, если мы сталкиваемся с ним. В противном случае мы проигнорируем это, и пусть NullPointerException произойдет "естественно". Он не должен быть нулевым, поэтому по определению поиск нулевого значения является исключительной ситуацией.

Если ноль является допустимым значением, то это означает, что ноль имеет семантическое значение. Скорее всего, это означает, что значение «отсутствует» или «недействительно». Здесь есть два подслучаа: (1a) null означает то же самое, что и пустая строка, или (1b) это означает что-то другое.

Если у вас есть случай (1b), то я бы сказал, что вам нужна новая сущность в вашей доменной модели. Например, вы можете создать класс, подобный PaymentTerm, который имеет отдельные методы .isValid() и .isPresent(), а также метод доступа .asString() для получения строкового значения, если оно присутствует. (Существует множество возможных способов сделать класс PaymentTerm, с множеством возможных компромиссов: дело не в том, что вам нужна эта конкретная форма, а в том, что вам нужно на что-то больше, чем необработанный String что-то, от чего вы можете повесить методы, потому что эта вещь теперь является первоклассной сущностью в вашей доменной модели.)

Если у вас есть регистр (1a), тогда null и пустая строка означают одно и то же, семантически. Но они очень разные синтаксически! В пустой строке уже есть метод экземпляра для проверки (.isEmpty()), и его можно безопасно хранить, передавать, сравнивать с другими строками и т. Д.

Таким образом, case (1a) имеет два возможных решения: (1a.1) вы передаете как нулевую, так и пустую строку, и везде, где вы должны проверять любую из них, или (1a.2) вы нормализуете нули для пустых строк в самая быстрая возможность, а затем обрабатывать нуль как недопустимое значение и везде использовать пустую строку. В зависимости от формата ввода вы можете даже получить это поведение «бесплатно» (например, пустое текстовое поле, естественно, имеет пустую строку в качестве значения, а не ноль).

Мой аргумент в том, что регистр (1a.1) является запахом кода. Вместо того, чтобы обойти как нулевую, так и пустую строку и часто проверять их (вручную или с помощью метода, подобного isNullOrEmpty или isNotBlank), вы должны попытаться перейти к case (2) или case (1a.2) .

Обратите внимание, что этот ответ фактически подразумевает, что и isNotBlank и != null являются неоптимальными! В хорошо продуманной кодовой базе вы должны стремиться избегать их обоих, но я склонен думать, что вы должны стремиться избегать чего-то вроде isNotBlank и даже больше.

Тем не менее, как вы проверяете на ноль, или пустая строка не очень важна. JIT почти наверняка встраивает проверки в любом случае, и во многих случаях оптимизатор глазка полностью их исключает, если он может доказать нулевую безопасность другим способом. Гораздо важнее рассмотреть, является ли null допустимым значением в вашей программе, и если да, то, что это означает семантически, чтобы значение было нулевым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...