Nie możemy być pewni, co właściwie myśleli projektanci Javy podczas projektowania, Stringale możemy tylko wywnioskować te powody na podstawie korzyści, jakie uzyskujemy z niezmienności ciągów. Niektóre z nich są
1. Istnienie puli stałych łańcuchów
Jak omówiono w artykule Dlaczego ciąg jest przechowywany w puli stałych ciągów , każda aplikacja tworzy zbyt wiele obiektów łańcuchowych, aby uchronić JVM przed tworzeniem wielu obiektów łańcuchowych, a następnie zbieraniem ich bezużytków. JVM przechowuje wszystkie obiekty łańcuchowe w oddzielnym obszarze pamięci o nazwie pula stałych ciągów i ponownie wykorzystuje obiekty z tej puli buforowanej.
Za każdym razem, gdy tworzymy literał łańcuchowy, JVM najpierw sprawdza, czy ten literał jest już obecny w stałej puli, czy nie, a jeśli tam jest, nowe odniesienie zacznie wskazywać na ten sam obiekt w SCP.
String a = "Naresh";
String b = "Naresh";
String c = "Naresh";
W powyższym przykładzie obiektu String o wartości Nareshdostanie utworzony w SCP tylko raz i wszystkie odniesienia a, b, cbędzie wskazywać na ten sam obiekt, ale co, jeśli staramy się zmianę anp a.replace("a", "").
Idealnie, apowinna mieć wartość Nresh, ale b, cpowinny pozostać niezmienione, ponieważ jako użytkownika końcowego jesteśmy dokonującej zmiany w atylko. I wiemy a, b, cwszystkie są skierowane do tego samego obiektu, więc jeśli mamy dokonać zmiany a, inne powinny również odzwierciedlać zmiany.
Ale niezmienność ciągów znaków ratuje nas od tego scenariusza, a ze względu na niezmienność obiektu string obiektu string Nareshnigdy się nie zmieni. Więc kiedy wprowadzamy jakąkolwiek zmianę azamiast zmiany w obiekcie łańcuchowym, NareshJVM tworzy nowy obiekt, przypisz go, aa następnie dokonamy zmiany w tym obiekcie.
Zatem pula String jest możliwa tylko ze względu na niezmienność String i gdyby String nie był niezmienny, wówczas buforowanie obiektów typu string i ponowne ich użycie nie byłoby możliwe, ponieważ każda zmienna zmieniłaby wartość i zepsułaby inne.
I dlatego jest obsługiwany przez JVM w bardzo specjalny sposób i otrzymał specjalny obszar pamięci.
2. Bezpieczeństwo wątków
Obiekt jest nazywany bezpiecznym wątkowo, gdy działa na nim wiele wątków, ale żaden z nich nie jest w stanie uszkodzić swojego stanu, a obiekt ma ten sam stan dla każdego wątku w dowolnym momencie.
Ponieważ niezmienny obiekt nie może być modyfikowany przez nikogo po jego utworzeniu, co sprawia, że każdy niezmienny obiekt jest domyślnie bezpieczny dla wątków. Nie musimy stosować do niego żadnych środków bezpieczeństwa wątków, takich jak tworzenie zsynchronizowanych metod.
Tak więc ze względu na swoją niezmienną naturę obiekt string może być współużytkowany przez wiele wątków i nawet jeśli jest manipulowany przez wiele wątków, nie zmieni swojej wartości.
3. Bezpieczeństwo
W każdej aplikacji musimy podać kilka sekretów, np. Nazwę użytkownika \ hasła, adresy URL połączeń i ogólnie wszystkie te informacje są przekazywane jako obiekt ciągu.
Załóżmy teraz, że jeśli String nie byłby niezmienny z natury, spowodowałby poważne zagrożenie bezpieczeństwa dla aplikacji, ponieważ te wartości mogą się zmieniać, a jeśli jest to dozwolone, mogą się one zmienić z powodu błędnie napisanego kodu lub innej osoby, która mają dostęp do naszych referencji zmiennych.
4. Ładowanie klasy
Jak omówiono w sekcji Tworzenie obiektów przez odbicie w Javie z przykładem , możemy użyć Class.forName("class_name")metody do załadowania klasy do pamięci, która ponownie wywoła inne metody, aby to zrobić. Nawet JVM używa tych metod do ładowania klas.
Ale jeśli widzisz wyraźnie, że wszystkie te metody akceptują nazwę klasy jako obiekt ciągu, ciągi są używane do ładowania klas java, a niezmienność zapewnia bezpieczeństwo, przez które ładowana jest właściwa klasa ClassLoader.
Załóżmy, że jeśli String nie byłby niezmienny i próbujemy załadować, java.lang.Objectktóre zmieniają się org.theft.OurObjectw międzyczasie, a teraz wszystkie nasze obiekty mają zachowanie, które ktoś może wykorzystać do niepożądanych rzeczy.
5. Buforowanie HashCode
Jeśli zamierzamy wykonać jakiekolwiek operacje związane z haszowaniem na jakimkolwiek obiekcie, musimy nadpisać hashCode()metodę i spróbować wygenerować dokładny kod mieszający przy użyciu stanu obiektu. Jeśli stan obiektu się zmienia, co oznacza, że jego kod skrótu również powinien się zmienić.
Ponieważ String jest niezmienny, więc wartość przechowywana przez jeden obiekt ciągu nigdy nie ulegnie zmianie, co oznacza, że jego kod skrótu również się nie zmieni, co daje klasie String możliwość buforowania jego kodu skrótu podczas tworzenia obiektu.
Tak, obiekt String buforuje swój kod skrótu w momencie tworzenia obiektu, co czyni go doskonałym kandydatem do operacji związanych z haszowaniem, ponieważ kod skrótu nie musi być ponownie obliczany, co pozwala nam zaoszczędzić trochę czasu. Z tego powodu String jest najczęściej używany jako HashMapklucze.
Przeczytaj więcej o tym, dlaczego ciąg jest niezmienny i ostateczny w języku Java .