Почему в Java нет String.Empty? - PullRequest
224 голосов
/ 10 августа 2010

Я понимаю, что каждый раз, когда я набираю строковый литерал "", в пуле строк указывается один и тот же объект String.

Но почему String API не включает public static final String Empty = "";, поэтому я мог бы использовать ссылки на String.Empty?

Это сэкономит время компиляции, по крайней мере, поскольку компилятор будет знать, что он ссылается на существующую строку, и не должен проверять, был ли он уже создан для повторного использования, верно? И лично я считаю, что распространение строковых литералов, особенно крошечных, во многих случаях является «запахом кода».

Так что за String.Empty не было Великой Причины Дизайна, или создатели языка просто не разделяли мои взгляды?

Ответы [ 10 ]

169 голосов
/ 10 августа 2010

String.EMPTY - 12 символов, "" - два, и они оба будут ссылаться на один и тот же экземпляр в памяти во время выполнения. Я не совсем уверен, почему String.EMPTY сэкономит время компиляции, на самом деле я думаю, что это будет последний вариант.

Особенно с учетом того, что String являются неизменяемыми, вы не можете сначала получить пустую строку и выполнить с ней некоторые операции - лучше всего использовать StringBuilder (или StringBuffer, если вы хотите быть потокобезопасными ) и превратить это в строку.

Обновление
Из вашего комментария на вопрос:

Что вдохновило это на самом деле TextBox.setText("");

Я полагаю, что было бы вполне законно предоставить константу в вашем соответствующем классе:

private static final String EMPTY_STRING = "";

А затем ссылаться на него как в вашем коде как

TextBox.setText(EMPTY_STRING);

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

105 голосов
/ 05 ноября 2014

Использование org.apache.commons.lang.StringUtils.EMPTY

25 голосов
/ 28 августа 2010

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

if ("".equals(text))

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

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

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

7 голосов
/ 10 августа 2010

Если вам действительно нужна константа String.EMPTY, вы можете создать в своем проекте статический финальный класс утилиты с именем «Константы» (например).Этот класс будет поддерживать ваши константы, включая пустую строку ...

В той же идее вы можете создавать константы ZERO, ONE int ..., которые не существуют в классе Integer, но, как я прокомментировал, было бы больно писать и читать:

for(int i=Constants.ZERO; ...) {
    if(myArray.length > Constants.ONE) {
        System.out.println("More than one element");
    }
}

И т.д.

7 голосов
/ 10 августа 2010

Apache StringUtils также решает эту проблему.

Недостатки других опций:

  • isEmpty () - небезопасно. Если строка равна нулю, выбрасывает NPE
  • length () == 0 - опять-таки небезопасно. Также не учитывает пробельные строки.
  • Сравнение с ПУСТОЙ константой - май не быть в безопасности. Проблема пробелов

Предоставленный StringUtils - это еще одна библиотека, которую можно перетаскивать, но она работает очень хорошо и экономит массу времени и хлопот, проверяя наличие нулей или изящную обработку NPE.

5 голосов
/ 01 сентября 2018

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

Речь идет о симметрии , без которой API труднее использовать для людей. Ранние Java SDK, как известно, игнорировали это правило, и теперь уже слишком поздно. Вот несколько примеров на моей голове, не стесняйтесь вставить свой «любимый» пример:

  • BigDecimal.ZERO, но без AbstractCollection.EMPTY, String.EMPTY
  • Array.length но List.size ()
  • List.add (), Set.add (), но Map.put (), ByteBuffer.put () и давайте не будем забывать StringBuilder.append (), Stack.push ()
5 голосов
/ 10 августа 2010

Все эти литералы "" являются одним и тем же объектом.Зачем делать все эти дополнительные сложности?Это просто больше текста и менее понятно (стоимость компилятора минимальна).Поскольку строки Java являются неизменяемыми объектами, их вообще не нужно различать, за исключением, возможно, эффективности, но с пустым строковым литералом это не имеет большого значения.постоянный, сделай сам.Но все, что он будет делать, это поощрять еще более подробный код; никогда не принесет никакой пользы.

3 голосов
/ 10 августа 2010

Чтобы добавить к сказанному Ноэлем М, вы можете посмотреть на этот вопрос, и этот ответ показывает, что константа используется повторно.

http://forums.java.net/jive/message.jspa?messageID=17122

Строковая константа всегда "интернирована" так что на самом деле нет необходимости в таких постоянная.

String s=""; String t=""; boolean b=s==t; // true
2 голосов
/ 10 августа 2010

Я понимаю, что каждый раз, когда я набираю строковый литерал "", в пуле строк указывается один и тот же объект String.
Там нет такой гарантии сделано. И вы не можете полагаться на это в своем приложении, это полностью зависит от JVM.

или создатели языка просто не разделяют мои взгляды?
Ага. Мне кажется, это вещь с очень низким приоритетом.

0 голосов
/ 03 марта 2012

Для тех, кто утверждает, что "" и String.Empty взаимозаменяемы или что "" лучше, вы очень ошибаетесь.

Каждый раз, когда вы делаете что-то вроде myVariable = "";вы создаете экземпляр объекта.Если бы Java-объект String имел открытую константу EMPTY, был бы только 1 экземпляр объекта ""

Например: -

String.EMPTY = ""; //Simply demonstrating. I realize this is invalid syntax

myVar0 = String.EMPTY;
myVar1 = String.EMPTY;
myVar2 = String.EMPTY;
myVar3 = String.EMPTY;
myVar4 = String.EMPTY;
myVar5 = String.EMPTY;
myVar6 = String.EMPTY;
myVar7 = String.EMPTY;
myVar8 = String.EMPTY;
myVar9 = String.EMPTY;

10 (11 включая String.EMPTY).object

Или: -

myVar0 = "";
myVar1 = "";
myVar2 = "";
myVar3 = "";
myVar4 = "";
myVar5 = "";
myVar6 = "";
myVar7 = "";
myVar8 = "";
myVar9 = "";

10 указателей на 10 объектов

Это неэффективно и во всех больших приложениях может быть значительным.

ВозможноJava-компилятор или среда выполнения достаточно эффективны, чтобы автоматически указывать все экземпляры "" на один и тот же экземпляр, но это может и не потребовать дополнительной обработки для этого определения.

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