Рекомендуется ли StringUtils.EMPTY?

91

Вы используете StringUtils.EMPTYвместо ""?

Я имею в виду либо возвращаемое значение, либо если вы устанавливаете значение переменной String. Я не имею в виду сравнение, потому что мы используемStringUtils.isEmpty()

keuleJ
источник

Ответы:

111

Конечно, нет. Вы действительно думаете, что "" недостаточно ясно?

Константы имеют по существу 3 варианта использования:

  1. Задокументируйте значение значения (с постоянным именем + javadoc)
  2. Синхронизируйте клиентов по общему значению.
  3. Предоставьте ярлык для специального значения, чтобы избежать некоторых затрат на инициализацию

Здесь не применяются.

Давид Пьер
источник
33
Я все еще вижу один незначительный и редкий вариант использования StringUtils.EMPTY. Это дает понять, что используется пустая строка, а не какая-то лень («О, это требует String, давайте пройдем ""»). Если кто-то обнаружит этот фрагмент кода, он дважды подумает, прежде чем вносить изменения. Кроме того, если бы они StringUtils.EMPTYбыли определены как ваша собственная переменная, например MyClass.EMPTY, внесение изменений в «это представление пустоты» потребовало бы изменения одной строки кода. Вы можете, например, заменить его "<empty>"на пустую строку "". Но я думаю, что это заходит слишком далеко.
Timmos
5
Наконец, у меня есть разумный аргумент, к которому я могу рекомендовать фанатиков, вместо того чтобы каждый раз думать самостоятельно. Спасибо.
Alex
2
Как ПУСТОТА не имеет смысла? EMPTY удовлетворяет как 1, так и 2 в вашем списке. Опытные разработчики сильно недооценивают возможность того, что младшие разработчики могут испортить такую ​​простую вещь, как использование "".
Эндрю Т. Финнелл
4
@AndrewTFinnell имя EMPTYне имеет никакого значения, которого еще не имеет сама пустая строка. В частности, он не документирует, почему вы решили использовать пустую строку в этом конкретном случае. Это не отличается от присвоения имени константе ONEи притворства, что есть смысл использовать эту константу вместо значения.
Хольгер
6
Голосование "против" только потому, что нет, я на самом деле не думаю, что "" достаточно ясно :( Оно пустое? Оно пустое? Есть ли там место, которое я не вижу, потому что мой размер шрифта маленький? Это было предназначено для быть пустым? Есть ли какие-нибудь странные "невидимые" символы?
Дэн Рейсон
60

Я использую StringUtils.EMPTY, для сокрытия литерала, а также для выражения того, что return StringUtils.EMPTYполностью ожидалось, и должна возвращать пустую строку, ""может привести к предположению, что ""его можно легко изменить на что-то еще и что это, возможно, было всего лишь ошибкой. Думаю, EMPTYвыразительнее.

Кристофер Клевес
источник
37
По мнению других, которые предлагали это: вы также используете ZERO для 0 и ONE для 1?
Джон Скит,
9
Я бы не стал сравнивать специальный «пустой» случай с использованием целочисленного литерала.
Кристофер Клевес,
16
Я нахожу StringUtils.EMPTY менее выразительным, чем "".
bacar
1
@JonSkeet Большое вам респект. Мне кажется, что вы здесь неправы. Хотя мы с вами, возможно, никогда не столкнемся с этим, нужно сделать случай, чтобы не использовать буквальный "", поскольку он не обеспечивает проверки синтаксиса, если разработчик его испортил. И да, я видел, как младшие разработчики портят простые вещи вроде "". Я не верю в то, что когда-либо заменять EMPTY чем-то другим, кроме "". Мне нравится идея EMPTY только потому, что компилятор может понять ее значение.
Эндрю Т. Финнелл
@AndrewTFinnell: «Неправильно» - странный термин для обозначения того, что определенно должно быть субъективным. Нет, я не ожидаю, что EMPTY когда-либо изменит значение, но я, как и бакар, нахожу ""более выразительным, чем использование StringUtils.EMPTY, и то, что вы сказали, не изменило моего мнения по этому поводу. Я почти могу поверить в то, что разработчики очень, очень редко пишут пустой строковый литерал неправильно, но я возьму ясность строкового литерала за один раз на миллион (и, надеюсь, легко обнаруживается при тестировании ... ) ошибка, лично.
Джон Скит
29

Нет, просто используйте "".

Буквально ""чистый, как кристалл. Нет никакого недопонимания относительно того, что имелось в виду. Я бы не знал, зачем вам для этого нужна константа класса. Я могу только предположить, что эта константа используется во всем пакете, содержащем StringUtilsвместо "". Однако это не значит, что вы должны его использовать.

Если на тротуаре есть камень, его не нужно бросать.

Эрик Робертсон
источник
6
«Если на тротуаре есть камень, его не нужно бросать». Скажи это моему 6-летнему сыну.
roel
14

Я поражен тем, как много людей счастливы слепо предполагать, что "" действительно пустая строка и не содержит (случайно?) Каких-либо замечательных невидимых и непробельных символов Unicode. Ради любви ко всему хорошему и порядочному, всегда используйте ПУСТОЙ.

j__m
источник
4
Мне любопытно - вы когда-нибудь видели, чтобы это происходило в коде? Если да, то случайно или намеренно? Казалось бы, это сложно сделать случайно, и если бы я делал это специально, я мог бы с такой же легкостью создать свой собственный класс StringUtils с непустой константой EMPTY и ссылаться на него.
Ян Робертсон,
5
@IanRobertson Да, я видел это. На самом деле довольно часто. Люди постоянно копируют и вставляют данные с веб-сайтов и из одного набора кодов в другой. Есть также компании, которые все еще используют Clear Case, который использует архаичный кодовый набор, который затем слепо транслируется в набор Windows ISO, а затем переводится в UTF-8, если вы переходите на Git. Я потратил бесчисленное количество часов на исправление проблем с кодовым набором. Включая этот.
Эндрю Т. Финнелл
3
@AndrewTFinnell Я, конечно, понимаю, как в целом это могло вызвать проблемы. Но как часто вы видели непустую, выглядящую пусто, строковую константу?
Ian Robertson
13

Я добавлю сюда свои два цента, потому что я не вижу, чтобы кто-нибудь говорил об Stringинтернировании и инициализации класса:

  • Все Stringлитералы в источниках Java интернированы, что делает любой "" и StringUtils.EMPTYтот же объект
  • Использование StringUtils.EMPTY может инициализировать StringUtilsкласс, поскольку он обращается к своему статическому члену EMPTY только в том случае, если он не объявленfinal (JLS специфичен для этой точки). Однако это окончательный вариант, поэтому он не будет инициализировать класс.org.apache.commons.lang3.StringUtils.EMPTY

См. Соответствующий ответ по интернированию строк и инициализации класса со ссылкой на JLS 12.4.1 .

Матье
источник
«Только если оно не объявлено окончательным», поэтому, поскольку это поле объявлено окончательным, доступ к нему не может вызвать инициализацию StringUtilsкласса.
Holger
@Holger, это было общее утверждение, но на самом деле я отредактировал ссылку на javadoc, показывающую, что он окончательный (и, следовательно, не будет инициализировать класс).
Matthieu
8

Я не очень люблю его использовать, return "";т.к. короче чем return StringUtils.EMPTY.

Однако одно ложное преимущество его использования заключается в том, что если вы вводите return " ";вместо return "";, вы можете столкнуться с другим поведением (относительно того, правильно ли вы тестируете пустую строку или нет).

Ромен Линсолас
источник
13
Вы когда-нибудь замечали, что это действительно проблема (используя "" случайно там, где вы имели в виду "")? Лично я считаю буквальный текст более читаемым, и это никогда не доставляло мне никаких проблем.
Джон Скит,
2
@Jon Нет, конечно, но я пытался найти преимущество в его использовании;)
Romain Linsolas
1
Не существует правила равного времени. Если нет преимущества, то нет и преимущества.
Эрик Робертсон
1
Мне также не нравится "", я ненавижу набирать одну и ту же буквальную строку более одного раза, даже иногда только один раз. Я бы предпочел объявить константы в Constants.java , но не повторять их везде в исходном коде.
賈 可 Джеки
2
Я ДУМАЮ, return ""; это уродливо, Я ПРЕДПОЧИТАЮ использовать return StringUtil.EMPTY(объявленный в моем собственном классе StringUtil , а НЕ Apache StringUtils ).
賈 可 Джеки
5

Если ваш класс не использует что-либо еще из общего пользования, было бы жаль иметь эту зависимость только для этого магического значения.

Дизайнер StringUtils интенсивно использует эту константу, и это правильно, но это не означает, что вы должны использовать и ее.

херувим
источник
Я имел в виду, что это приемлемо, поскольку автор решил пойти этим путем (избегайте использования «магических значений»). Однако это должно быть приватным.
cherouvim
Автор часто использует 0 в коде. Было бы лучше, если бы они также определили константу int ZERO = 0? Если нет, то какая разница?
Джон Скит,
6
Это зависит от контекста. Если бы это был FCKEditorStringUtils, их EMPTY был бы «<p> & nbsp </p>», и я бы предпочел, чтобы EMPTY использовался повторно вместо того, чтобы реплицировать это магическое значение повсюду в классе. Итак, под EMPTY они, вероятно, имеют в виду EMPTY_CONTENT, а не EMPTY_STRING (так что ваш пример ZERO немного несправедлив). Не могли бы вы повторно использовать константу ERROR_VISA_INVALID = 0?
cherouvim
1

Честно говоря, я не вижу в этом особого смысла. Если вы хотите сравнить, например, с пустой строкой, просто используйтеStringUtils.isNotEmpty(..)

Божо
источник
2
StringUtils.isNotEmpty(..)также выполняет нулевую проверку, поэтому это не совсем то же самое, что сравнение с пустой строкой.
cherouvim
и как ты будешь жить null? в качестве 2-го аргумента equals, но результат будет тот же -false
Божо
isNotEmptyявляется противоположностью "".equals(…), следовательно, тот факт, что он будет рассматриваться nullкак пустая строка , отличается от сравнения с пустой строкой, "".equals("")true, "".equals(null)false, StringUtils.isNotEmpty("")false, StringUtils.isNotEmpty(null)false. Если вы просто хотите узнать, пуста ли строка, используйте string.isEmpty(), который имеет правильное поведение: возвращает, trueесли это пустая строка, и бросает, NullPointerExceptionесли строка null
Хольгер
1

Я нахожу StringUtils.EMPTYполезным в некоторых случаях для разборчивости. В частности, с:

  1. Тернарный оператор, например.

    item.getId() != null ? item.getId() : StringUtils.EMPTY;
    
  2. Возвращаю пустую строку из метода, чтобы подтвердить, что да, я действительно хотел это сделать.

Также с помощью константы создается ссылка на StringUtils.EMPTY. В противном случае, если вы попытаетесь создать экземпляр строкового литерала ""каждый раз, когда JVM должна будет проверять, существует ли он уже в пуле строк (что, вероятно, будет, поэтому никаких дополнительных накладных расходов на создание экземпляра). Разумеется, использование StringUtils.EMPTYпозволяет избежать проверки пула строк?

Том
источник
4
Ваш аргумент с множественными поисками не работает. В главе 13.4.9 Спецификации языка Java 3.0 упоминается, что StringUtils.EMPTYконстанта разрешается во время компиляции.
Роланд Иллиг
4
Существование в пуле строк проверяется во время компиляции и загрузки класса, а не во время выполнения, когда вы выполняете такой оператор,
Маркиз Лорн
1
Поскольку StringUtil.EMPTYэто константа времени компиляции, ссылка на нее компилируется в тот же байт-код, что и при ""прямом использовании . Кроме того, я не понимаю, почему тернарный оператор должен иметь какое-либо значение. Это выражение похоже на любое другое. Любая причина использовать или не использовать именованную константу также применима к тернарному оператору.
Хольгер
1

Нет, потому что мне нужно еще написать. И пустая строка является независимой от платформы пустой (в Java).

File.separator лучше, чем "/" или "\".

Но делай как хочешь. Вы не можете получить опечатку вродеreturn " ";

Кристиан Куетбах
источник
7
Я совершенно не понимаю, почему большинство программистов так боятся писать «слишком много». Написав StringUtils.EMPTY, вы получите код с самокомментариями, который легче читать. И согласно Стиву МакКоннеллу (или некоторому исследованию, которое он цитировал в Code Complete 2.0) код читается в 7 раз больше, чем написано.
Paweł Dyda
1
Вы совершенно правы, НО: "" .equals (someString) так же легко читается, как StringUtils.EMPTY.equals (someString)
Кристиан Кютбах
StringUtils.EMPTY.equals (someString) приведет к синтаксической ошибке, если вы напишете его неправильно. "" .equals (someString) не будет. Это единственная причина, по которой нужно использовать EMPTY.
Эндрю Т Финнелл
1
@AndrewTFinnell, поэтому someString.isEmpty()вместо этого пишут нормальные программисты .
Holger
-2

Да, в этом есть смысл. Возможно, это не единственный путь, но я очень мало вижу в том, чтобы сказать, что это «не имеет смысла».

По моему мнению:

  • Выделяется больше чем "".
  • Это объясняет, что вы имели в виду пустой, и этот пробел, скорее всего, не подходит.
  • Если вы не определите собственную переменную и не будете использовать ее в нескольких местах, ее все равно придется менять везде.
  • Если вы не разрешаете в коде свободные строковые литералы, это помогает.
Орон
источник
It will still require changing everywhere if you don't define your own variable and use it in multiple places.вы собираетесь заменить пустую строку на другую?
Пита
@Pita Извини, это была плохая фраза. Я хотел сказать, что если вы используете этот встроенный вместо "", вы все равно не получите тех же преимуществ, что и определение своей собственной константы и повторное использование в нескольких местах. Это не аргумент для StringUtils.EMPTY, это объяснение, которое вы не получите многого, даже если оно «имеет смысл». Лично я бы создал константу с описательным именем, а затем назначил бы это. Я видел несколько случаев, когда разработчик предполагал один пробел и в итоге получал пустую строку, чего не бывает с этой формой.
Орон