Prečo je reťazec Immutable v Jave?

1. Úvod

V Jave sú reťazce nemenné. Zjavná otázka, ktorá v rozhovoroch dosť často prevláda, je „Prečo sú reťazce navrhnuté v jazyku Java ako nemenné?“

James Gosling, tvorca Java, sa raz v rozhovore pýtal, kedy by sa malo používať nemenné, na ktoré odpovedá:

Použil by som nemenný, kedykoľvek to bude možné.

Ďalej podporuje svoj argument, v ktorom uvádza funkcie, ktoré poskytuje nemennosť, ako je ukladanie do pamäte cache, zabezpečenie, ľahké opätovné použitie bez replikácie atď.

V tomto tutoriále ďalej preskúmame, prečo sa návrhári jazyka Java rozhodli zachovať String nemenný.

2. Čo je to nemenný objekt?

Nemenný objekt je objekt, ktorého vnútorný stav zostane po úplnom vytvorení konštantný. To znamená, že akonáhle je objekt priradený k premennej, nemôžeme nijako aktualizovať referenciu ani mutovať vnútorný stav.

Máme samostatný článok, ktorý podrobne pojednáva o nemenných objektoch. Ďalšie informácie nájdete v článku Immutable Objects in Java.

3. Prečo je String Nezmeniteľné v Jave?

Kľúčovými výhodami udržania tejto triedy v nezmeniteľnej podobe sú ukladanie do pamäte cache, zabezpečenie, synchronizácia a výkon.

Poďme diskutovať o tom, ako tieto veci fungujú.

3.1. Predstaviť String Bazén

The String je najpoužívanejšia dátová štruktúra. Ukladanie do medzipamäte String literály a ich opätovné použitie šetrí veľa haldy miesta, pretože je odlišné String premenné sa vzťahujú na rovnaký objekt v String bazén. String interný bazén slúži presne na tento účel.

Java String Pool je oblasť špeciálnej pamäte, kde Struny sú uložené JVM. Odkedy Struny sú nemenné v Jave, JVM optimalizuje množstvo im pridelenej pamäte tým, že ukladá iba jednu kópiu každého literálu String v bazéne. Tento proces sa nazýva interning:

Reťazec s1 = "Hello World"; Reťazec s2 = "Hello World"; assertThat (s1 == s2) .isTrue ();

Z dôvodu prítomnosti String pool v predchádzajúcom príklade, dve rôzne premenné ukazujú na rovnaké String objekt z fondu, čím sa ušetrí rozhodujúci pamäťový zdroj.

Máme samostatný článok venovaný Jave String Bazén. Viac informácií nájdete v tomto článku.

3.2. Bezpečnosť

The String je široko používaný v Java aplikáciách na ukladanie citlivých informácií, ako sú užívateľské mená, heslá, adresy URL pripojení, sieťové pripojenia atď. Tiež ho hojne používajú nakladače tried JVM pri načítaní tried.

Preto zabezpečenie String triedy je zásadné z hľadiska bezpečnosti celej aplikácie všeobecne. Zvážte napríklad tento jednoduchý útržok kódu:

void criticalMethod (String userName) {// vykonávať bezpečnostné kontroly, ak (! isAlphaNumeric (userName)) {throw new SecurityException (); } // urob sekundárne úlohy initializeDatabase (); // kritická úloha connection.executeUpdate ("UPDATE Customers SET Status = 'Active'" + "WHERE UserName = '" + userName + "'"); }

Vo vyššie uvedenom útržku kódu povedzme, že sme dostali a String objekt z nedôveryhodného zdroja. Spočiatku robíme všetky potrebné bezpečnostné kontroly, aby sme skontrolovali, či String je iba alfanumerický, po ktorom nasleduje niekoľko ďalších operácií.

Pamätajte, že naša metóda nespoľahlivých volajúcich zdrojov na to stále odkazuje meno používateľa objekt.

Ak Struny boli premenlivé, potom si v čase vykonania aktualizácie nemôžeme byť istí, že String sme dostali, aj po vykonaní bezpečnostných kontrol, by sme boli v bezpečí. Metóda nedôveryhodného volajúceho má stále referenciu a môže zmeniť String medzi kontrolami integrity. Takto je náš dopyt v tomto prípade náchylný na SQL injekcie. Tak premenlivé Struny by mohlo viesť k zhoršeniu bezpečnosti v priebehu času.

Môže sa tiež stať, že Stringmeno používateľa je viditeľný pre iné vlákno, ktoré by potom mohlo po kontrole integrity zmeniť svoju hodnotu.

Všeobecne sa v tomto prípade zachráni nemennosť, pretože je ľahšie pracovať s citlivým kódom, keď sa hodnoty nezmenia, pretože existuje menej vkladaní operácií, ktoré by mohli ovplyvniť výsledok.

3.3. Synchronizácia

Byť nemenný automaticky robí String bezpečné pre vlákna, pretože sa nezmenia pri prístupe z viacerých vlákien.

Preto nemenné objekty možno vo všeobecnosti zdieľať vo viacerých vláknach bežiacich súčasne. Sú tiež bezpečné pre vlákna pretože ak vlákno zmení hodnotu, potom namiesto úpravy tej istej nové String by sa vytvoril v String bazén. Teda Struny sú bezpečné pre viacvláknové spracovanie.

3.4. Ukladanie do medzipamäte Hashcode

Odkedy String objekty sa hojne používajú ako dátová štruktúra, tiež sa často používajú v hash implementáciách ako HashMap, HashTable, HashSetatď. Keď pracujete na týchto hash implementáciách, hashCode () metóda sa nazýva bucketing pomerne často.

Nemennosť zaručuje Struny že sa ich hodnota nezmení. Takže the hashCode () metóda je prepísaná v String triedy na uľahčenie ukladania do pamäte cache, takže sa hash vypočítava a ukladá do pamäte cache počas prvého hashCode () hovoru a odvtedy sa vráti rovnaká hodnota.

To zase zvyšuje výkonnosť zbierok, ktoré pri implementácii používajú hash implementácie String predmety.

Na druhej strane premenlivé Struny by produkoval dva rôzne hashcodes v čase vloženia a načítania, ak by obsah String bol po operácii upravený a potenciálne stratil objekt hodnoty v Mapa.

3.5. Výkon

Ako sme už videli predtým, String bazén existuje, pretože Struny sú nemenné. Na druhej strane zvyšuje výkon tým, že šetrí haldy pamäte a rýchlejší prístup k hash implementáciám, keď je prevádzkovaný s Struny.

Odkedy String je najbežnejšie používaná dátová štruktúra zlepšujúca výkonnosť String majú podstatný vplyv na zlepšenie výkonu celej aplikácie všeobecne.

4. Záver

Prostredníctvom tohto článku to môžeme uzavrieť Reťazce sú nemenné presne tak, aby ich odkazy mohli byť považované za normálnu premennú a dalo by ich prechádzať okolo, medzi metódami a cez vlákna, bez obáv z toho, či skutočný String objekt, na ktorý ukazuje, sa zmení.

Dozvedeli sme sa tiež, aké môžu byť ďalšie dôvody, ktoré viedli k Java jazykových dizajnérov, aby bola táto trieda nemenná.


$config[zx-auto] not found$config[zx-overlay] not found