2015-04-09 2 views
22

В чем разница между следующими двумя инициализациями в Java?В чем разница между инициализацией String новой String() и новой строкой ("") в Java?

  1. String a = new String();
  2. String b = new String("");
+2

Уже очень похожая должность для этого. http://stackoverflow.com/questions/9555077/string-initialization-difference –

+0

Возможный дубликат [String пустой конструктор в java] (http://stackoverflow.com/questions/12430112/string-empty-constructor-in -java) – Joe

+1

@Joe Хотя я в шоке, этого уже не существует, я не думаю, что этот вопрос является дубликатом этого - 'String (" ")' отличается от '' ''. –

ответ

19

Ну, это почти то же самое.

public static void main(String[] args) { 
    String s1 = new String(); 
    String s2 = new String(""); 
    System.out.println(s1.equals(s2)); // returns true. 
} 

Небольшие различия (довольно незначительные):

  1. new String(); занимает меньше времени, чем для выполнения new String("");, поскольку конструктор копирования делает много вещей.

  2. new String("") добавляет пустой String ("") в пул констант String, если он еще не присутствует.

Кроме этого, нет никаких других отличий

Примечания: Использование new String("abc") это почти всегда плохо, потому что вы будете создавать 2 строки один на постоянных Струнном пуле, а другие на кучу с тем же значением ,

+1

Другая разница - 'new String();' также легко и занимает меньше времени для ввода (означает запись), поэтому его предпочтительнее. –

+3

@GrijeshChauhan Почему не просто '' ''? – johnchen902

+1

@ johnchen902 yes '=" "' лучше, я просто сравнивал два указанных вопроса. –

4

Java Docs объясняет это красиво

Это 2 разные конструктор вызова

public String() 

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

public String(String original) 

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

2

В первом случае вы создаете только один String объект во втором случае два: "" и new String, если "" объект уже не существует в строке пула.

  1. инициализацию вновь созданный объект String, так что она представляет собой пустую последовательность символов .

  2. Инициализирует вновь созданный объект String так, чтобы он представлял такую ​​же последовательность символов, что и аргумент; другими словами, созданная строка является копией строки аргумента.

+1

Создается ли '' '' 'в этот момент? или он уже существует в объединенном пуле строк? –

+0

@MichaelT Спасибо за вопрос. Если вы еще не создали другой '' '' строковый объект ранее, он будет создан. Если вы создадите '' '' строковый объект раньше, значение будет получено из пула строк. –

+0

Мое чтение [этого ответа] (http: // stackoverflow.com/a/16785991/289086) предполагает, что интернирование строк выполняется во время загрузки класса (как его часть пула констант для класса), а не при вызове метода. Таким образом, при вызове метода не создается новая строка для '' ''. Просто небольшая коррекция (я думаю). –

3

Внутри, различные конструкторы будут вызываться.

Однако, в результате String объекты будут идентичны по своему содержанию и равным (a.equals(b) вернется true)

1

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

2

TheLostMind в основном правильно, но я хотел бы добавить, что конструктор копирования не на самом деле сделать это много:

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/lang/String.java#137

137 public String() {
138 this.value = newchar[0];
139 }

151 public String(String original) {
152 this.value = original.value;
153 this.hash = original.hash;
154 }

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

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

+0

Мне интересно, что с учетом строки в миллион символов 'foo' оператор' bar = new string (foo); 'будет совместно использовать хранилище резервных копий, но вызов метода' foo.equals (bar) 'будет сравнивать каждый символ этого резервного хранилища для себя, вместо того, чтобы заметить, что обе строки имеют один и тот же резервный магазин. – supercat

+0

Ну, до java7u40 в конструкторе копирования много чего происходило. Теперь они изменили дизайн так, что используется тот же базовый массив. В jdk 6 мы использовали для создания нового массива char в конструкторе копирования :) – TheLostMind

1

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

Чтобы инициализировать переменный с пустой строкой, сделайте следующее:

String s = ""; 

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