Почему в Java нет String.Empty?

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

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

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

Так был ли проект Grand Design Reason позади ни одного String.Empty, или создатели языка просто не делились моими взглядами?

Ответ 1

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

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

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

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

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

private static final String EMPTY_STRING = "";

И затем ссылайтесь на него как на свой код как

TextBox.setText(EMPTY_STRING);

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

Ответ 2

Используйте org.apache.commons.lang.StringUtils.EMPTY

Ответ 3

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

if ("".equals(text))

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

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

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

Ответ 4

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

Сбой других параметров:

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

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

Ответ 5

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

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

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

Etc.

Ответ 6

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

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

Ответ 7

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

Что касается симметрии, то без нее 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()

Ответ 8

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

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

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

String s=""; String t=""; boolean b=s==t; // true

Ответ 9

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

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

Ответ 10

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

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

Например: -

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) Указатели на 1 объект

Или: -

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

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

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

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