Hvorfor er streng uforanderlig i Java?

1. Introduksjon

I Java er strenger uforanderlig. Et åpenbart spørsmål som er ganske utbredt i intervjuer er "Hvorfor strenger er designet som uforanderlige i Java?"

James Gosling, skaperen av Java, ble en gang spurt i et intervju når skulle man bruke uforanderlige, som han svarer på:

Jeg vil bruke en uforanderlig når jeg kan.

Han støtter videre sitt argument om funksjoner som uforanderlighet gir, som hurtigbufring, sikkerhet, enkel gjenbruk uten replikering, etc.

I denne opplæringen vil vi nærmere undersøke hvorfor Java-språkdesignerne bestemte seg for å beholde String uforanderlig.

2. Hva er et uforanderlig objekt?

Et uforanderlig objekt er et objekt hvis indre tilstand forblir konstant etter at den er helt opprettet. Dette betyr at når objektet har blitt tildelt en variabel, kan vi verken oppdatere referansen eller mutere den interne tilstanden på noen måte.

Vi har en egen artikkel som diskuterer uforanderlige gjenstander i detalj. For mer informasjon, les artikkelen Immutable Objects in Java.

3. Hvorfor er det? String Uforanderlig i Java?

De viktigste fordelene ved å holde denne klassen som uforanderlig er cache, sikkerhet, synkronisering og ytelse.

La oss diskutere hvordan disse tingene fungerer.

3.1. Introduser til String Basseng

De String er den mest brukte datastrukturen. Caching av String bokstaver og gjenbruk av dem sparer mye masse plass fordi forskjellige String variabler refererer til det samme objektet i String basseng. String internt basseng tjener akkurat dette formålet.

Java String Pool er det spesielle minneområdet der Strenger lagres av JVM. Siden Strenger er uforanderlige i Java, optimaliserer JVM mengden minne som er tildelt dem ved å lagre bare en kopi av hver bokstavelig String i bassenget. Denne prosessen kalles interning:

String s1 = "Hello World"; String s2 = "Hello World"; assertThat (s1 == s2) .isTrue ();

På grunn av tilstedeværelsen av String i forrige eksempel, to forskjellige variabler peker mot det samme String objekt fra bassenget, og sparer dermed viktig minnesressurs.

Vi har en egen artikkel dedikert til Java String Basseng. For mer informasjon, gå videre til den artikkelen.

3.2. Sikkerhet

De String brukes mye i Java-applikasjoner for å lagre følsomme deler av informasjon som brukernavn, passord, tilkoblings-URL-er, nettverkstilkoblinger osv. Den brukes også mye av JVM-klasselastere mens du laster inn klasser.

Derfor sikring String klasse er avgjørende når det gjelder sikkerheten til hele søknaden generelt. Tenk for eksempel på denne enkle kodebiten:

ugyldig criticalMethod (String brukernavn) {// utfør sikkerhetskontroller hvis (! isAlphaNumeric (brukernavn)) {kast nytt SecurityException (); } // gjør noen sekundære oppgaver initializeDatabase (); // kritisk oppgaveforbindelse.executeUpdate ("UPDATE Customers SET Status = 'Active'" + "WHERE UserName = '" + userName + "'"); }

La oss si at vi mottok en i kodebiten ovenfor String objekt fra en upålitelig kilde. Vi gjør alle nødvendige sikkerhetskontroller først for å sjekke om String er bare alfanumerisk, etterfulgt av noen flere operasjoner.

Husk at vår upålitelige kildeanropsmetode fremdeles har referanse til dette brukernavn gjenstand.

Hvis Strenger var mutable, så når vi utfører oppdateringen, kan vi ikke være sikre på at String vi mottok, selv etter å ha utført sikkerhetskontroller, ville være trygt. Den upålitelige anropsmetoden har fremdeles referansen og kan endre String mellom integritetskontroller. Dermed gjør spørringen vår utsatt for SQL-injeksjoner i dette tilfellet. Så foranderlig Strenger kan føre til forringelse av sikkerheten over tid.

Det kan også skje at Stringbrukernavn er synlig for en annen tråd, som deretter kan endre verdien etter integritetskontrollen.

Generelt kommer uforanderlighet til vår redning i dette tilfellet fordi det er lettere å operere med sensitiv kode når verdiene ikke endres fordi det er færre sammenflettinger av operasjoner som kan påvirke resultatet.

3.3. Synkronisering

Å være uforanderlig gjør automatisk String trådsikker siden de ikke blir endret når de er tilgjengelige fra flere tråder.

Derfor uforanderlige objekter, generelt, kan deles på tvers av flere tråder som kjører samtidig. De er også trådsikre fordi hvis en tråd endrer verdien, så i stedet for å endre den samme, en ny String ville bli opprettet i String basseng. Derfor, Strenger er trygge for flertråding.

3.4. Hashcode-hurtigbufring

Siden String objekter blir rikelig brukt som datastruktur, de blir også mye brukt i hash-implementeringer som HashMap, HashTable, HashSetosv. Når du bruker disse hasjimplementeringene, hashCode () metoden kalles ganske ofte for skuffing.

Uforanderligheten garanterer Strenger at verdien deres ikke endres. Så de hashCode () metoden overstyres i String klasse for å legge til rette for hurtigbufring, slik at hasjen beregnes og bufres i løpet av den første hashCode () samtale og samme verdi returneres siden.

Dette forbedrer i sin tur ytelsen til samlinger som bruker hash-implementeringer når de brukes med String gjenstander.

På den annen side, foranderlig Strenger ville produsere to forskjellige hashkoder på tidspunktet for innsetting og henting hvis innholdet i String ble endret etter operasjonen, og potensielt miste verdiobjektet i Kart.

3.5. Opptreden

Som vi så tidligere, String bassenget eksisterer fordi Strenger er uforanderlige. I sin tur forbedrer den ytelsen ved å spare hukommelsesminne og raskere tilgang til hash-implementeringer når den brukes Strenger.

Siden String er den mest brukte datastrukturen, og forbedrer ytelsen til String har en betydelig effekt på å forbedre ytelsen til hele applikasjonen generelt.

4. Konklusjon

Gjennom denne artikkelen kan vi konkludere med det Strenger er uforanderlige nettopp slik at referansene deres kan behandles som en normal variabel, og man kan føre dem rundt, mellom metoder og på tvers av trådene, uten å bekymre seg for om den faktiske String objektet det peker på vil endre seg.

Vi lærte også hva som kan være de andre grunnene som førte til Java språkdesignere for å gjøre denne klassen som uforanderlig.


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