2009-02-27 6 views
7
String s1 = "BloodParrot is the man"; 
String s2 = "BloodParrot is the man"; 
String s3 = new String("BloodParrot is the man"); 

System.out.println(s1.equals(s2)); 
System.out.println(s1 == s2); 
System.out.println(s1 == s3); 
System.out.println(s1.equals(s3)); 

// output
vero
vero
falso
verouguaglianza String vs parità di posizione

Perché non tutte le corde hanno la stessa posizione nella memoria se tutti e tre hanno lo stesso contenuto?

+0

È questo Java o C#. La risposta alla tua domanda sembra dipendere dalla lingua. Potresti voler taggare di conseguenza. –

+0

Questo non è un duplicato. Questa domanda riguarda più l'interning string che la comparazione. –

+0

Immagino che l'ultimo commento non abbia senso a meno che non menzioni che ho eseguito il rollback di una modifica dicendo che questa domanda era una copia di un'altra. Sentiti libero di aggiungere il link e vota per chiudere se non sei d'accordo. –

risposta

15

Java solo stagisti interni String letterali. I nuovi oggetti String (creati utilizzando la parola chiave new) non sono internati per impostazione predefinita. È possibile utilizzare il metodo String.intern() per internare un oggetto String esistente. La chiamata a intern controllerà il pool String esistente per un oggetto corrispondente e lo restituirà se ne esiste uno o lo aggiungerà se non ci fosse alcuna corrispondenza.

Se si aggiunge la linea

s3 = s3.intern(); 

al codice destra dopo aver creato s3, vedrete la differenza nella vostra uscita.

See some more examples and a more detailed explanation.

Questo naturalmente richiama l'argomento molto importante su quando utilizzare == e quando utilizzare il metodo equals in Java. Quasi sempre si desidera utilizzare equals quando si tratta di riferimenti a oggetti. L'operatore == confronta i valori di riferimento, ovvero quasi mai ciò che intendi confrontare. Conoscere la differenza aiuta a decidere quando è opportuno utilizzare == o equals.

3

Si chiama esplicitamente new per s3 e questo lascia una nuova istanza della stringa.

+0

Oh, quindi l'unica differenza è l'uso della parola chiave "nuova". Quindi le stringhe che non usano la nuova parola chiave non sono istanze di un oggetto stringa? – BloodParrot

+0

Sono istanze, ma potrebbero non avere necessariamente buffer dedicati. – sharptooth

1

Perché non tutte le stringhe hanno la stessa posizione in memoria se tutte e tre hanno lo stesso contenuto?

Perché sono diverse stringhe con lo stesso contenuto!

+0

String s1 = "BloodParrot is the man"; String s2 = "BloodParrot è l'uomo"; s1 == s2 => true Sembra che s1 e s2 siano le stringhe SAME. –

+0

Sì. Scusate. Mi sbagliavo! :( – Bharani

+0

Questi due * sono * identici, che puntano allo stesso indirizzo.Solo s3 è diverso, perché è creato esplicitamente come una nuova stringa – erickson

2

Creare un String è in realtà un processo rapido. Cercando di trovare qualsiasi String creato in precedenza sarà molto più lento.

Considerare ciò che è necessario fare per rendere tutti gli interni di String s. È necessario cercare un set di tutti i String s costruiti in precedenza. Nota questo deve essere fatto in un modo sicuro per i thread, che aggiunge un overhead. Perché non vuoi che questo perda, è necessario utilizzare qualche forma di riferimenti non forti (thread-safe).

Naturalmente, non è possibile implementare Java in questo modo perché la libreria espone sfortunatamente i costruttori per String s e molti altri oggetti valore immutabili.

1

C'è un metodo chiamato String.intern che, in pratica, prende tutte le stringhe uguali e le inserisce in una tabella hash (io sono una specie di bugiardo, ma per questo è il concetto che conta, non la realtà).

String s1 = "BloodParrot is the man"; 
String s2 = "BloodParrot is the man"; 
String s3 = new String("BloodParrot is the man").intern(); 

System.out.println(s1.equals(s2)); 
System.out.println(s1 == s2); 
System.out.println(s1 == s3); 
System.out.println(s1.equals(s3)); 

dovrebbero essere tutti "veri". Questo perché (e sto mentendo un po 'di nuovo qui, ma conta ancora solo per il concetto non realtà) String s1 = "BloodParrot is the man"; è fatto qualcosa come String s1 = "BloodParrot is the man" .intern();