2015-04-09 12 views
22

Jaka jest różnica między dwoma następującymi inicjacjami w Javie?Jaka jest różnica między inicjalizacjami ciągów przez nowy ciąg() i nowy ciąg ("") w języku Java?

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

Już bardzo podobny post do tego. http://stackoverflow.com/questions/9555077/string-initialization-difference –

+0

możliwy duplikat [String pusty konstruktor w java] (http://stackoverflow.com/questions/12430112/string-empty-constructor-in -java) – Joe

+1

@Joe Chociaż jestem zszokowany, to już nie istnieje, nie sądzę, że to pytanie jest duplikatem tego - 'String (" ")' różni się od '" ". –

Odpowiedz

19

Cóż, są one prawie takie same.

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

Niewielkie różnice (raczej nieznaczna):

  1. new String(); zajmuje mniej czasu na wykonanie niż new String(""); ponieważ konstruktor kopia robi wiele rzeczy.

  2. new String("") dodaje pusty ciąg ("") do puli stałych String, jeśli jeszcze jej nie ma.

Inne niż to, nie istnieją żadne inne różnice

Uwaga: Korzystanie z new String("abc") prawie zawsze jest złe, ponieważ będzie stworzenie 2 Strings jeden na stałe łańcuchowe basen, a inny na sterty o tej samej wartości .

+1

inna różnica - 'new String();' jest także łatwa i zajmuje mniej czasu na pisanie, więc jest to lepsze. –

+3

@GrijeshChauhan Dlaczego nie tylko "" "? – johnchen902

+1

@ johnchen902 yes '=" "' jest lepsze, właśnie porównywałem dwie podane w pytaniu. –

4

Java Docs wyjaśnia to pięknie

Są 2 inny konstruktor nazywając

public String() 

Inicjuje nowo utworzony obiekt String, który reprezentuje pustą sekwencję znaków. Zauważ, że użycie tego konstruktora jest niepotrzebne, ponieważ ciągi są niezmienne.

public String(String original) 

Inicjuje nowo utworzony obiekt String tak, że reprezentuje sam ciąg znaków jako argument; innymi słowy, nowo utworzony ciąg znaków jest kopią ciągu argumentów. Jeśli nie jest potrzebna wyraźna kopia oryginału , użycie tego konstruktora jest niepotrzebne ponieważ ciągi znaków są niezmienne.

2

W pierwszym przypadku utworzyć tylko jedną String obiektu w drugim przypadku dwa: "" i new String, jeśli "" obiekt nie istnieje już w basenie strun.

  1. Inicjuje nowo utworzony obiekt String tak, że reprezentuje pusty ciąg znaków.

  2. Inicjuje nowo utworzony obiekt String, tak aby reprezentował on tę samą sekwencję znaków co argument; innymi słowy, nowo utworzony ciąg znaków jest kopią ciągu argumentów.

+1

Czy "" "jest tworzone w tym miejscu? lub czy już istnieje w puli internowanych łańcuchów? –

+0

@MichaelT Dzięki za pytanie. Jeśli wcześniej nie utworzyłeś innego obiektu '' "' string, zostanie on utworzony. Jeśli wcześniej stworzysz obiekt tekstowy '' ", wartość zostanie pobrana z puli łańcuchów. –

+0

Moje czytanie [tej odpowiedzi] (http: // stackoverflow.com/a/16785991/289086) sugeruje, że interakcja String jest wykonywana w czasie ładowania klasy (jako jej część puli stałej dla klasy) - nie wtedy, gdy wywoływana jest metoda. W związku z tym nie jest tworzony nowy ciąg dla '" "', gdy metoda jest wywoływana. Tylko niewielka korekta (chyba). –

3

Wewnętrznie różnych konstruktorów zostanie wywołany.

Jednak powstałe String obiekty będą identyczne za ich treść i równe (a.equals(b) powróci true)

1

Pierwszym z nich jest wywołanie konstruktora domyślnego, a drugi jest wywołaniem konstruktora kopii w celu stworzenia nowy ciąg w każdym przypadku.

2

TheLostMind jest głównie poprawne, ale chciałbym dodać, że konstruktor kopia rzeczywistości nie zrobić wiele:

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 }

Korzystanie stałą "" użyje pierwszego konstruktora utwórz odwołanie do obiektu mimo to, więc nie ma znaczenia, którego z nich używasz.

W każdym przypadku, polecam używanie literału literowego "", ponieważ można zapisać odniesienie do obiektu, jeśli używasz tego ciągu w innym miejscu. Używaj tylko konstruktora String, jeśli naprawdę potrzebujesz kopii tego ciągu, który nie jest używany nigdzie indziej.

+0

Ciekawe, że biorąc pod uwagę milionowy ciąg znaków 'foo', wyrażenie' bar = new string (foo); 'podzieli się ze sklepem, ale wywołanie metody' foo.equals (bar) 'będzie porównywać każdy znak tego samego sklepu, zamiast zauważać, że oba łańcuchy mają ten sam zapas. – supercat

+0

Cóż - przed wersją java7u40 dużo się działo w konstruktorze kopii. Teraz zmienili projekt, aby użyć tej samej tablicy back-end. W jdk 6 stworzyliśmy nową tablicę znaków w konstruktorze kopii :) – TheLostMind

1

Z czysto praktycznego punktu widzenia istnieje zero różnica między tymi konstrukcjami, ponieważ nigdy nie ma powodu, aby kiedykolwiek korzystać z któregokolwiek z nich. Są one zarówno marnotrawstwem, jak i nadmierną komplikacją, a więc równie bezsensowne.

Aby zainicjować zmienną z pustym ciągiem znaków, zrobić:

String s = ""; 

To jest krótsza i jaśniej do pisania, i zapobiega tworzeniu żadnych obiektów String, ponieważ jeden wspólny "" instancji w intern basenie będzie z pewnością zostały już załadowane przez jakąś inną klasę.