Чи рекомендується StringUtils.EMPTY?


91

Ви використовуєте StringUtils.EMPTYзамість ""?

Я маю на увазі або як повернене значення, або якщо ви встановлюєте значення змінної String. Я не маю на увазі порівняння, тому що там ми використовуємоStringUtils.isEmpty()

Відповіді:


111

Звичайно, ні. Ви дійсно вважаєте "" недостатньо зрозумілим?

Константи мають, по суті, 3 варіанти використання:

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

Жодне тут не застосовується.


33
Я все ще бачу один незначний і рідкісний випадок використання StringUtils.EMPTY. Зрозуміло, що використання порожнього рядка призначене, а не якась лінь ("О, для цього потрібен рядок, давайте пройдемо """). Якщо хтось вдарить цей фрагмент коду, він двічі подумає, перш ніж вносити зміни. Крім того, якби StringUtils.EMPTYбуло визначено як власну змінну, наприклад MyClass.EMPTY, для внесення змін до "цього подання порожнечі" потрібно було б змінити один рядок коду. Наприклад, ви можете змінити його на "<empty>"замість порожнього рядка "". Але, я думаю, це заходить занадто далеко.
Тіммос

5
Нарешті, у мене є якийсь розумний аргумент, який слід передати фанатикам, замість того, щоб кожен раз міркувати самостійно. Дякую.
Олексій

2
Як ПУСТО не вистачає сенсу? EMPTY відповідає як 1, так і 2 у вашому списку. Досвідчені розробники сильно недооцінюють можливість молодших розробників зіпсувати щось таке просте, як використання "".
Andrew T Finnell,

4
@AndrewTFinnell ім'я EMPTYне несе жодного значення, якого сам порожній рядок ще не має. Найголовніше, це не документує, чому ви вирішили використовувати порожній рядок у цьому конкретному випадку. Це не інакше, як називати константу ONEі робити вигляд, що був сенс використовувати цю константу замість значення.
Holger

6
Голоси проти лише тому, що ні, я насправді не думаю, що "" є досить зрозумілим :( Чи порожнє? Чи порожнє? Чи є там місце, яке я не бачу, оскільки мій розмір шрифту невеликий? бути порожніми? Чи є якісь дивні "невидимі" символи?
Ден Рейсон

60

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


37
Відповідно до інших, хто запропонував це: чи використовуєте ви також ZERO для 0 та ONE для 1?
Джон Скіт,

9
Я б не порівнював особливий "порожній" випадок із використанням цілочисельного літералу.
Крістофер Клевес,

16
Я вважаю StringUtils.EMPTY менш виразним, ніж "".
bacar

1
@JonSkeet Велика повага до вас. Я справді відчуваю, що ви тут помиляєтесь. Хоча ми з вами ніколи не можемо зіткнутися з цим, існує випадок, щоб не використовувати "" літерал, оскільки він не передбачає перевірки синтаксису, якщо розробник його псує. І так, я бачив, як молодші розробники псують такі прості речі, як "". Я не погоджуюсь на ідею коли-небудь змінювати ПУСТО, щоб означати щось інше, ніж "". Мені подобається ідея EMPTY лише тим фактом, що компілятор може зрозуміти її значення.
Andrew T Finnell,

@AndrewTFinnell: "Неправильно" - це дивний термін для того, що, безперечно, має бути суб'єктивним. Ні, я не очікую, що EMPTY коли-небудь змінить значення, але я - як bacar - виявляю ""виразніше, ніж використання StringUtils.EMPTY, і те, що ви сказали, не передумало з цього приводу. Я майже можу повірити, що розробники неправильно написали порожній літерал рядка дуже, дуже інколи - але я візьму ясність рядкового літералу за один раз на мільйон (і його легко знайти в тестуванні, сподіваюся ... ) помилка, особисто.
Джон Скіт,

29

Ні, просто використовуйте "".

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

Якщо на тротуарі є камінь, його не потрібно кидати.


6
"Якщо на тротуарі є камінь, його не потрібно кидати". Скажи це моєму 6-річному синові.
roel

14

Я вражений тим, як багато людей із задоволенням сліпо припускають, що "" насправді є порожнім рядком і не містить (випадково?) Жодного чудового невидимого символу, що не має пробілів. Для любові до всього доброго і пристойного, використовуйте ПУСТО, коли тільки можете.


4
Мені цікаво - ви коли-небудь бачили, як це відбувалося в коді? Якщо так, це було випадково чи навмисно? Здавалося б, це складно зробити випадково, і якби навмисно, я міг би так само легко створити свій власний клас StringUtils з непустою константою EMPTY і посилатися на це.
Ян Робертсон,

5
@IanRobertson Так, я бачив, як це сталося. Насправді досить часто. Люди постійно вирізають та вставляють із веб-сайтів та з одного набору кодів на інший набір кодів. Є також компанії, які все ще використовують Clear Case, який використовує архаїчний набір кодів, який потім наосліп перекладається у набір ISO Windows, а потім перекладається в UTF-8, якщо ви перейдете до Git. Я витратив незліченну кількість годин, виправляючи проблеми з набором кодів. В тому числі і цей.
Andrew T Finnell,

3
@AndrewTFinnell Я напевно бачу, як загалом це може спричинити проблеми. Але як часто ви конкретно бачили не пусту порожню на вигляд константу рядка?
Ян Робертсон,

13

Я додаю тут свої два центи, тому що я не бачу, щоб хтось говорив про Stringінтернування та ініціалізацію класу:

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

Дивіться відповідну відповідь щодо інтернування рядків та ініціалізації класу , посилаючись на JLS 12.4.1 .


“Лише якщо воно не оголошено остаточним”, тому оскільки це поле оголошено остаточним, доступ до нього не може спричинити ініціалізацію StringUtilsкласу.
Холгер

@Holger, це було загальне твердження, але справді, я відредагував посиланням на javadoc, показуючи, що він остаточний (і, отже, не ініціалізує клас).
Матьє

8

Я не дуже люблю користуватися ним, як return "";і коротше ніж return StringUtils.EMPTY.

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


13
Ви коли-небудь спостерігали, що насправді це проблема (використовуючи "" випадково там, де ви мали на увазі "")? Особисто я вважаю буквальний текст більш читабельним, і це ніколи не створювало мені проблем.
Джон Скіт,

2
@Jon Ні, справді, але я намагався знайти перевагу його використання;)
Ромен Лінсолас

1
Не існує правила рівного часу. Якщо переваги немає, то переваги немає.
Ерік Робертсон,

1
Мені також не подобається "", я ненавиджу вводити один і той же буквальний рядок більше одного разу, навіть раз лише іноді. Я вважаю за краще оголосити константи в Constants.java , але не повторювати їх всюди у вихідному коді.
賈 可 Джекі

2
Я ДУМАЮ, що return ""; це потворно, Я ВАЖЛИВИ використовувати return StringUtil.EMPTY(оголошений у власному класі StringUtil , А НЕ StringUtils Apache ).
賈 可 Jacky

5

Якщо ваш клас не використовує нічого іншого із спільного, тоді буде шкода мати цю залежність саме для цієї магічної цінності.

Дизайнер StringUtils активно використовує цю константу, і це правильно, але це не означає, що вам слід також використовувати її.


Я мав на увазі, що це прийнятно, оскільки автор вирішив піти цим шляхом (уникайте будь-якого використання "магічних цінностей"). Це має бути приватним.
cherouvim

Автор часто використовує 0 в коді. Чи було б для них краще також визначити константу int ZERO = 0? Якщо ні, то яка різниця?
Джон Скіт,

6
Це залежить від контексту. Якби це був FCKEditorStringUtils, їх ПУСТО буде "<p> & nbsp </p>", і я волів би, щоб ПІЗНО було використано повторно, замість того, щоб повторювати це магічне значення скрізь у класі. Отже, під 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. В іншому випадку, якщо ви намагаєтеся створити екземпляр літералу String ""кожного разу, коли JVM доведеться перевіряти, чи він уже існує в пулі рядків (що, швидше за все, і буде, тому жодних додаткових екземплярів не буде створено). Напевно, використання StringUtils.EMPTYдозволяє уникнути необхідності перевіряти пул рядків?


4
Ваш аргумент із кількома пошуками не підтримується. У главі 13.4.9 Специфікації мови Java 3.0 зазначено, що StringUtils.EMPTYконстанта вирішується під час компіляції.
Роланд Ілліг,

4
Існування в пулі рядків перевіряється під час компіляції та часу завантаження класу, а не під час виконання будь-коли, коли ви виконуєте таку заяву,
Marquis of Lorne

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) не буде. Це єдина причина, через яку потрібно використовувати ПУСТО.
Andrew T Finnell,

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, це пояснення того, що ви не отримуєте багато, навіть якщо це "має сенс". Особисто я створив би константу з описовим ім'ям, а потім або призначив це. Я бачив кілька випадків, коли розробник призначав єдиний пробіл і закінчував порожнім рядком, чого не відбувається з цією формою.
Орон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.