Я чувствую, что предпосылка этого вопроса уже неверна. Вам не нужно проверять наличие нулевых строк в большинстве мест - на самом деле, я бы сказал, что вам следует избегать использования 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
допустимым значением в вашей программе, и если да, то, что это означает семантически, чтобы значение было нулевым.