Zwykle tworzymy obiekty za pomocą new
słowa kluczowego, na przykład:
Object obj = new Object();
Ciągi znaków to obiekty, ale nie używamy ich new
do ich tworzenia:
String str = "Hello World";
Dlaczego to? Czy mogę zrobić string z new
?
java
string
core
new-operator
giri
źródło
źródło
new String(...)
zostało to użyte do obejścia szczegółów implementacji podczas tworzenia podciągów dużych ciągów. Zostało to naprawione w Javie 7 i nie jest już konieczne.Odpowiedzi:
Oprócz tego, co już zostało powiedziane, literały ciągów [tj. Ciągi znaków takie jak,
"abcd"
ale nie lubiąnew String("abcd")
] w Javie są internalizowane - oznacza to, że za każdym razem, gdy odwołujesz się do „abcd”, otrzymujesz odniesienie do pojedynczejString
instancji, a nie do nowej za każdym razem. Więc będziesz mieć:ale gdybyś miał
wtedy jest to możliwe
(a na wypadek, gdyby ktoś potrzebował przypomnienia, zawsze używaj
.equals()
do porównania ciągów;==
testy na równość fizyczną).Internowanie literałów String jest dobre, ponieważ często są używane więcej niż raz. Na przykład rozważ (wymyślony) kod:
Gdybyśmy nie mieli internowania ciągów znaków, „Następna iteracja” musiałaby zostać zainicjowana 10 razy, podczas gdy teraz zostanie utworzona tylko raz.
źródło
Łańcuchy to „specjalne” obiekty w Javie. Projektanci Javy mądrze zdecydowali, że ciągi znaków są używane tak często, że potrzebowali własnej składni oraz strategii buforowania. Kiedy deklarujesz ciąg, mówiąc:
myString jest odwołaniem do obiektu String z wartością „coś”. Jeśli później zadeklarujesz:
Java jest wystarczająco sprytna, aby dowiedzieć się, że myString i myOtherString są takie same i przechowują je w globalnej tabeli String jako ten sam obiekt. Polega on na tym, że nie możesz modyfikować ciągów znaków, aby to zrobić. Zmniejsza to ilość wymaganej pamięci i może przyspieszyć porównania.
Jeśli zamiast tego napiszesz
Java utworzy dla Ciebie zupełnie nowy obiekt, inny niż obiekt myString.
źródło
Mam nadzieję, że to wyjaśnia kilka wątpliwości. :)
źródło
To jest skrót. Pierwotnie tak nie było, ale Java to zmieniła.
W tym FAQ omówiono to krótko. Poradnik specyfikacji języka Java również o tym mówi. Ale nie mogę znaleźć tego online.
źródło
String podlega kilku optymalizacjom (z braku lepszej frazy). Zauważ, że String ma również przeciążenie operatorów (dla operatora +) - w przeciwieństwie do innych obiektów. Jest to więc bardzo szczególny przypadek.
źródło
Zwykle używamy literałów String, aby uniknąć tworzenia niepotrzebnych obiektów. Jeśli użyjemy operatora new do stworzenia obiektu String, to za każdym razem będzie on tworzył nowy obiekt.
Przykład:
Dla powyższego kodu w pamięci:
źródło
W Javie ciągi są szczególnym przypadkiem, z wieloma regułami, które dotyczą tylko ciągów. Podwójne cudzysłowy powodują, że kompilator tworzy obiekt String. Ponieważ obiekty String są niezmienne, umożliwia to kompilatorowi internowanie wielu ciągów i tworzenie większej puli ciągów. Dwie identyczne stałe typu String będą zawsze miały to samo odniesienie do obiektu. Jeśli nie chcesz, aby tak było, możesz użyć new String („”), co spowoduje utworzenie obiektu String w czasie wykonywania. Metoda intern () była kiedyś powszechna i powodowała, że dynamicznie tworzone łańcuchy były porównywane z tabelą wyszukiwania ciągów. Po umieszczeniu łańcucha w internacie odwołanie do obiektu będzie wskazywać na kanoniczną instancję String.
Gdy classloader ładuje klasę, wszystkie stałe typu String są dodawane do puli String.
źródło
Cukier syntaktyczny. Plik
składnia jest nadal dostępna.
źródło
String small = new String(huge.substring(int, int));
, który umożliwia odtworzenie dużego źródłachar[]
z oryginalnegohuge
String.Nadal możesz używać
new String("string")
, ale byłoby trudniej tworzyć nowe ciągi bez literałów łańcuchowych ... musiałbyś używać tablic znaków lub bajtów :-) Literały ciągów mają jedną dodatkową właściwość: wszystkie te same literały ciągów z dowolnego punktu klasy do tego samego ciągu instancja (są internowani).źródło
Nie ma prawie potrzeby tworzenia nowego ciągu znaków, ponieważ literał (znaki w cudzysłowie) jest już obiektem typu String utworzonym podczas ładowania klasy hosta. Przywoływanie metod dosłownie i don jest całkowicie legalne, głównym rozróżnieniem jest wygoda, jaką zapewniają dosłowne. Byłoby wielkim problemem i stratą czasu, gdybyśmy musieli stworzyć tablicę znaków i wypełnić ją char po znaku, a oni zrobiliby nowy String (tablicę znaków).
źródło
Zapraszam do tworzenia nowego ciągu za pomocą
Zwykła notacja
s = "new String";
jest mniej więcej wygodnym skrótem - którego należy używać ze względu na wydajność, z wyjątkiem tych dość rzadkich przypadków, w których naprawdę potrzebujesz ciągów znaków, które kwalifikują się do równaniaEDYTOWAĆ
W odpowiedzi na komentarz: nie miała to być porada, a jedynie bezpośrednia odpowiedź na tezę pytających, że nie używamy słowa kluczowego „nowe” dla Strings, co po prostu nie jest prawdą. Mam nadzieję, że ta zmiana (w tym powyższa) trochę to wyjaśnia. Przy okazji - jest kilka dobrych i znacznie lepszych odpowiedzi na powyższe pytanie dotyczące SO.
źródło
new String(...)
chyba że twoja aplikacja WYMAGA od ciebie stworzenia łańcucha o odrębnej tożsamości.Pula literałów zawiera wszystkie ciągi znaków, które zostały utworzone bez użycia słowa kluczowego
new
.Jest różnica: ciąg znaków bez nowego odwołania jest przechowywany w puli literałów String, a ciąg znaków z new mówi, że znajdują się w pamięci sterty.
Łańcuchy z new są gdzie indziej w pamięci, tak jak każdy inny obiekt.
źródło
Ponieważ String jest niezmienną klasą w java.
Dlaczego jest niezmienny? Ponieważ String jest niezmienny, więc może być współużytkowany między wieloma wątkami i nie musimy synchronizować operacji String na zewnątrz. As String jest również używany w mechanizmie ładowania klas. Jeśli więc ciąg String był zmienny, wówczas java.io.writer mógł zostać zmieniony na abc.xyz.mywriter
źródło
Wynik:
Stworzyłem dwa oddzielne obiekty, oba mają pole (ref) „Name”. Więc nawet w tym przypadku "Jan Peter" jest udostępniany, jeśli rozumiem sposób, w jaki działa java.
źródło
Cóż, StringPool jest zaimplementowany przy użyciu The Hashmap w java. Jeśli tworzymy zawsze z nowym słowem kluczowym, nie wyszukuje go w String Pool i tworzy dla niego nową pamięć, która może być potrzebna później, jeśli mamy uruchomioną operację intensywnie wykorzystującą pamięć i jeśli tworzymy wszystkie ciągi z nowym słowem kluczowym, które wpłynęłoby na wydajność naszej aplikacji. Dlatego zaleca się, aby nie używać nowych słów kluczowych do tworzenia ciągu znaków, ponieważ tylko wtedy trafi on do puli String, która z kolei jest Hashmap (pamięć zapisana, wyobraź sobie, że mamy wiele ciągów utworzonych za pomocą nowego słowa kluczowego) tutaj zostanie on zapisany i jeśli ciąg już istnieje, odniesienie do niego (które zwykle znajduje się w pamięci Stack) zostanie zwrócone do nowo utworzonego ciągu. Zrobiono więc, aby poprawić wydajność.
źródło