Wat is het verschil tussen deze twee volgende uitspraken?
String s = "text";
String s = new String("text");
Antwoord 1, autoriteit 100%
new String("text");
maakt expliciet een nieuwe en referentieel verschillende instantie van een String
-object; String s = "text";
mag een instantie uit de stringconstante poolhergebruiken als die beschikbaar is.
U zeer zeldenzou ooit de new String(anotherString)
constructor willen gebruiken. Van de API:
String(String original)
: Initialiseert een nieuw gemaaktString
-object zodat het dezelfde reeks tekens vertegenwoordigt als het argument; met andere woorden, de nieuw gemaakte string is een kopie van de argumentstring. Tenzij een expliciete kopie van het origineel nodig is, is het gebruik van deze constructor niet nodig, aangezien strings onveranderlijk zijn.
Verwante vragen
- Java Strings: “String s = new String(”silly“);”
- Strings zijn objecten in Java, dus waarom gebruiken we ‘nieuw’ niet om ze te maken?
Wat referentieel onderscheid betekent
Bekijk het volgende fragment:
String s1 = "foobar";
String s2 = "foobar";
System.out.println(s1 == s2); // true
s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
==
op twee referentietypes is een referentie-identiteitsvergelijking. Twee objecten die equals
zijn, zijn niet noodzakelijk ==
. Het is meestal verkeerd om ==
te gebruiken voor referentietypes; meestal moet in plaats daarvan equals
worden gebruikt.
Desalniettemin, als u om welke reden dan ook twee equals
maar niet ==
strings moet maken, kuntde new String(anotherString)
-constructor. Het moet echter nogmaals gezegd worden dat dit heeleigenaardig is en zelden de bedoeling is.
Referenties
Verwante problemen
Antwoord 2, autoriteit 65%
String literalsgaat naar String Constant Zwembad.
De onderstaande momentopname kan u helpen om het visueelte begrijpen om het voor langere tijd te onthouden.
Object creatie regel voor regel:
String str1 = new String("java5");
Met behulp van de letterlijke tekenreeks “java5” in de constructor wordt een nieuwe tekenreekswaarde opgeslagen in de tekenreeksconstante pool.
Met de nieuwe operator wordt een nieuw tekenreeksobject in de heap gemaakt met “java5” als waarde.
String str2 = "java5"
Referentie “str2” verwijst naar reeds opgeslagen waarde in stringconstante pool
String str3 = new String(str2);
Er wordt een nieuw tekenreeksobject in de heap gemaakt met dezelfde waarde als referentie door “str2”
String str4 = "java5";
Referentie “str4” verwijst naar reeds opgeslagen waarde in stringconstante pool
Totaal aantal objecten: Heap – 2, Pool – 1
Meer informatie over de Oracle-community
Antwoord 3, autoriteit 7%
Men maakt een String in de String Constant Pool
String s = "text";
de andere maakt een string in de constante pool ("text"
) en een andere string in de normale heapruimte (s
). Beide strings hebben dezelfde waarde, die van “text”.
String s = new String("text");
s
gaat dan verloren (komt in aanmerking voor GC) als het later niet wordt gebruikt.
Letterlijke tekenreeksen daarentegen worden hergebruikt. Als je "text"
op meerdere plaatsen in je klas gebruikt, zal het in feite één en slechts één String zijn (d.w.z. meerdere verwijzingen naar dezelfde string in de pool).
Antwoord 4
@Braj: ik denk dat je het andersom hebt genoemd. Corrigeer me als ik het mis heb
Object creatie regel voor regel:
String str1 = nieuwe String(“java5”)
Pool- "java5" (1 Object)
Heap - str1 => "java5" (1 Object)
String str2 = “java5”
pool- str2 => "java5" (1 Object)
heap - str1 => "java5" (1 Object)
String str3 = nieuwe String(str2)
pool- str2 => "java5" (1 Object)
heap- str1 => "java5", str3 => "java5" (2 Objects)
String str4 = “java5”
pool - str2 => str4 => "java5" (1 Object)
heap - str1 => "java5", str3 => "java5" (2 Objects)
Antwoord 5
Denk aan dat "bla"
een magische fabriek is zoals Strings.createString("bla")
(pseudo). De fabriek heeft een verzameling van alle snaren die tot nu toe op deze manier zijn gemaakt.
Als het wordt aangeroepen, controleert het of er al een string in de pool is met deze waarde. Indien waar, retourneert het dit string-object, dus strings die op deze manier zijn verkregen, zijn inderdaad hetzelfde object.
Als dat niet het geval is, wordt intern een nieuw tekenreeksobject gemaakt, wordt het opgeslagen in de pool en wordt het geretourneerd. Dus wanneer dezelfde tekenreekswaarde de volgende keer wordt opgevraagd, wordt dezelfde instantie geretourneerd.
Het handmatig maken van new String("")
heft dit gedrag op door de letterlijke tekenreeks te omzeilen. Dus gelijkheid moet altijd worden gecontroleerd met behulp van equals()
die de tekenreeks vergelijkt in plaats van de objectreferentiegelijkheid.
Antwoord 6
Een eenvoudige manier om het verschil te begrijpen is hieronder:-
String s ="abc";
String s1= "abc";
String s2=new String("abc");
if(s==s1){
System.out.println("s==s1 is true");
}else{
System.out.println("s==s1 is false");
}
if(s==s2){
System.out.println("s==s2 is true");
}else{
System.out.println("s==s2 is false");
}
uitvoer is
s==s1 is true
s==s2 is false
Dus nieuwe String() zal altijd een nieuwe instantie maken.
Antwoord 7
Hoewel het er vanuit het oogpunt van programmeurs hetzelfde uitziet, heeft het een grote impact op de prestaties. Je zou bijna altijd het eerste formulier willen gebruiken.
Antwoord 8
String str = new String("hello")
Het zal controleren of String constant pool al String “hallo” bevat?
Indien aanwezig, zal het geen item toevoegen aan String constant pool. Als het niet aanwezig is, wordt er een item toegevoegd in de String-constante-pool.
Er wordt een object gemaakt in een heap-geheugengebied en str
referentiepunten naar het object dat is gemaakt in de heap-geheugenlocatie.
als je een str
verwijzing wilt naar een puntobject dat in String een constante pool bevat, dan moet je expliciet str.intern();
aanroepen
String str = "world";
Het zal controleren of String constant pool al String “hallo” bevat?
Indien aanwezig, zal het geen item toevoegen aan String constant pool. Als het niet aanwezig is, wordt er een item toegevoegd in de String-constante-pool.
In beide bovenstaande gevallen verwijst str
naar String "world"
aanwezig in Constant pool.
Antwoord 9
Als je een string opslaat als
String string1 = "Hello";
direct, dan maakt JVM een String-object met de opgegeven prijs tijdens een apart geheugenblok genaamd String-constante pool.
En wanneer we de neiging hebben om te proberen een andere String te produceren als
String string2 = "Hello";
JVM verifieert of er al dan niet een String-object met constante prijs bestaat binnen de String-constante-pool, in plaats van een geheel nieuw object te maken, wijst JVM de referentie van het bestaande object toe aan de nieuwe variabele.
En wanneer we String opslaan als
String string = new String("Hello");
met behulp van het nieuwe trefwoord wordt een gloednieuw object met de opgegeven prijs gemaakt, ongeacht de inhoud van de String-constante-pool.
Antwoord 10
Sorry voor het late antwoord, maar het broodnodige antwoord.
Eerst moeten we wat Java.lang.StringKlasse regels.
-
Letterlijke tekenreeksen, bijv.
String str="java";
(we gebruiken alleen dubbele aanhalingstekens)
zijn verschillend van String Object (we gebruiken een nieuw trefwoord)
bijv.String str=new String("java");
-
String is een onveranderlijk objectdwz als de waarde verandert, wordt een nieuw object gemaakt en naar u teruggestuurd, bijv. Zie de functies
replace() and replaceAll()
en nog veel meer. -
Dit creëert een probleem van veel String Object in Modification, dus de makers van Java kwamen met een idee genaamd StringPool. StringPool wordt opgeslagen in het heapgebied waar objectreferentiegegevens worden opgeslagen zoals we weten. String is
Char[]
(vóór java 9erg lang om te lezen) ofbyte
[](na java 9kort om te lezen). -
Letterlijke tekenreeksen worden opgeslagen in StringPool en tekenreeksobjecten worden opgeslagen in het gebruikelijke heap-objectgebied.
-
Als er veel JVM-heap voor initialisatie van objectstrings wordt voltooid in String Operations, heeft het Java-ontwikkelingsteam intern()oplossing dit verplaatst/verandert geheugenverwijzing naar StringPool.
Nog een goede link om java.lang.String beter te begrijpen
import java.util.*;
class GFG {
public static void main(String[] args)
{
String siteName1 = "java.com";
String siteName2 = "java.com";
String siteName3 = new String("java.com");
String siteName4 = new String("java.com").intern();
System.out.println("siteName1:::"+Integer.toHexString(System.identityHashCode(siteName1)));
System.out.println("siteName2:::"+Integer.toHexString(System.identityHashCode(siteName2)));
System.out.println("siteName3 creation Of New Object Without Interned:::"+Integer.toHexString(System.identityHashCode(siteName3)));//must be Diffrent bcoz new Object In Heap Area
System.out.println("siteName4 creation Of New Object With Interned:::"+Integer.toHexString(System.identityHashCode(siteName4)));//must be same MemoryAddress of siteName1,siteName2 and Interned, bcoz Objects Points to String pool Now
System.out.println(siteName1 == siteName2); // true
System.out.println(siteName1 == siteName3); // false this tells about lietral vs String Objects
String siteName5 = siteName3.intern(); // Interning will not change Original Object but gives us a new Object
System.out.println("siteName5 Interned from siteName3:::"+Integer.toHexString(System.identityHashCode(siteName5)));//must be same MemoryAddress of siteName1,siteName2 and Interned, bcoz Objects Points to String pool Now
System.out.println(siteName1 == siteName3); // false this tells about Immutability
System.out.println(siteName1 == siteName5); // true After Intering both are same
System.out.println(siteName1 == siteName4); // true
System.out.println(siteName5 == siteName4); // true
}
}