Стоит ли делать пустую строку постоянной? - PullRequest
24 голосов
/ 18 октября 2008

У меня есть сотрудник, который клянется

//in a singleton "Constants" class
public static final String EMPTY_STRING = "";

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

if (Constants.EMPTY_STRING.equals(otherString)) {
    ...
}

вместо

if ("".equals(otherString)) {
    ...
}

Я говорю, что это

  1. не стоит - не экономит место в пуле кучи / стека / строк
  2. некрасиво
  3. злоупотребление классом констант.

Кто здесь идиот?

Ответы [ 17 ]

65 голосов
/ 18 октября 2008

Строковые литералы интернированы по умолчанию, поэтому независимо от того, сколько раз вы ссылаетесь на "" в коде, будет только один пустой объект String. Я не вижу никакой выгоды в объявлении EMPTY_STRING. В противном случае вы можете также объявить ONE, TWO, THREE, FOUR и т. Д. Для целочисленных литералов.

Конечно, если вы хотите изменить значение EMPTY_STRING позже, удобно иметь его в одном месте;)

16 голосов
/ 18 октября 2008

С какой стати вы хотите глобальную переменную в Java? Джеймс Гослинг действительно пытался от них избавиться; не возвращайте их, пожалуйста.

Или

0 == possiblyEmptyString.length()

или

possiblyEmptyString.isEmpty() // Java 6 only

так же ясно.

7 голосов
/ 18 октября 2008

По иронии судьбы весь смысл констант состоит в том, чтобы сделать их легко изменяемыми. Поэтому, если ваш коллега не планирует переопределить EMPTY_STRING, чтобы он был чем-то другим, а не пустой строкой - что было бы действительно глупо, - преобразование подлинной фиксированной конструкции, такой как "", в константу - это плохо.

Как говорит Дэн Дайер, все равно, что определять постоянную ЕДИНИЦУ равной 1: она совершенно бессмысленна и будет крайне запутанной - потенциально рискованной - если кто-то ее переопределит.

7 голосов
/ 18 октября 2008

Я предпочитаю видеть EMPTY_STRING.

Это делает его английским. "" .equals "читает" иначе, чем EMPTY_STRING.equals.

6 голосов
/ 20 октября 2008

Ну, я тоже мог догадаться, но я сделал быстрый тест ... Почти как мошенничество ...

Произвольная строка проверяется различными методами. (несколько итераций)

Результаты показывают, что isEmpty () быстрее и действительно более читабелен; Если isEmpty () недоступен, length () является хорошей альтернативой.

Использование константы, вероятно, не стоит.

"".equals(someString())      :24735 ms
t != null && t.equals("")    :23363 ms
t != null && t.equals(EMPTY) :22561 ms
EMPTY.equals(someString())   :22159 ms
t != null && t.length() == 0 :18388 ms
t != null && t.isEmpty()     :18375 ms
someString().length() == 0   :18171 ms

В этом сценарии;

"IAmNotHardCoded".equals(someString())

Я бы предложил определить константу в соответствующем месте, поскольку глобальный класс для всех констант действительно отстой. Если подходящего места нет, возможно, вы делаете что-то не так ...

Customer.FIELD_SHOE_SIZE //"SHOE_SIZE"

Может считаться подходящим местом, где как;

CommonConstants.I__AM__A__LAZY__PROGRAMMER // true

нет.

Для BigIntegers и тому подобного я склонен в конечном итоге определять конечную статику локально; как:

private final static BigDecimal ZERO = new BigDecimal(0);
private final static BigDecimal B100 = new BigDecimal("100.00");

Это меня раздражает, и было бы неплохо с сахаром для BigInts и BigDecimals ...

4 голосов
/ 18 октября 2008

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

FWIW, C # имеет статическое свойство string. Пусто только для этой цели, и я считаю, что это значительно улучшает читаемость кода.

3 голосов
/ 19 октября 2009

В качестве касательной к вопросу я обычно рекомендую использовать служебную функцию, когда вы действительно проверяете «не полезное значение», а, в частности, пустую строку. В общем, я склонен использовать:

import org.apache.commons.lang.StringUtils;

// Check if a String is whitespace, empty ("") or null.
StringUtils.isBlank(mystr); 
// Check if a String is empty ("") or null.
StringUtils.isEmpty(mystr); 

Концепция заключается в том, что вышеупомянутые два:

  • Проверьте различные другие случаи, включая нулевую безопасность, и (что более важно)
  • Передает то, что вы пытаетесь проверить, а не как это проверить.
3 голосов
/ 18 октября 2008

Мне не нравится ни один из вариантов. Почему не if (otherString.length() == 0)

Редактировать: я на самом деле всегда код

if (otherString == null || otherString.length() == 0)
2 голосов
/ 18 октября 2008

Один из случаев, когда имеет смысл иметь константу со значением пустой строки, - это когда ваше имя фиксирует семантику значения. Например:

if (Constants.FORM_FIELD_NOT_SET.equals(form.getField("foobar"))) {
    ...
}

Это делает код более самодокументированным (кроме аргумента, что лучший дизайн - добавить метод, проверяющий, установлено ли поле для самой формы).

2 голосов
/ 05 декабря 2010

Дэвид Арно заявляет: -

По иронии судьбы весь смысл константы, чтобы сделать их легко изменчива

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

Очень редко меняются постоянные значения (отсюда и название). Чаще всего значения конфигурации изменяются, но сохраняются где-то как данные (например, файл конфигурации или запись в реестре)

Начиная с раннего программирования, константы использовались для превращения таких вещей, как загадочные шестнадцатеричные значения, такие как 0xff6d8da412, во что-то понятное человеку без ever намерения изменить значения.

const int MODE_READ       = 0x000000FF;
const int MODE_EXECUTE    = 0x00FF0000;
const int MODE_WRITE      = 0x0000FF00;
const int MODE_READ_WRITE = 0x0000FFFF;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...