Come si può inizializzare una stringa usando “”?


154

Se String è una classe come qualsiasi altra, come può essere inizializzata usando virgolette doppie?


25
String è una classe VIP. " "è già una stringa!
johnchen902,

2
Nessun significato speciale. Intendevo solo molto importante. Cioè, java.lang.Stringavere un trattamento speciale del linguaggio Java.
johnchen902,

16
Chi dice che la stringa sia "una classe come qualsiasi altra"? È una classe molto speciale, diversa dalle altre. Poiché la tua supposizione è falsa, la domanda non è realmente rispondibile.
Eric Lippert,

5
Solo perché la supposizione è falsa, non significa che la domanda non sia responsabile. E la risposta corretta ha già 197 voti.
Koray Tugay,

Risposte:


293

Java String è speciale

I progettisti di Java hanno deciso di conservare i tipi primitivi in ​​un linguaggio orientato agli oggetti, invece di rendere tutto un oggetto, in modo da migliorare le prestazioni del linguaggio. I primitivi sono memorizzati nello stack di chiamate, che richiedono meno spazi di archiviazione e sono più economici da manipolare. D'altra parte, gli oggetti vengono archiviati nell'heap del programma, il che richiede una gestione della memoria complessa e più spazi di archiviazione.

Per motivi di prestazioni, Java String è progettato per essere compreso tra una primitiva e una classe.

Per esempio

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

inserisci qui la descrizione dell'immagine

Nota: i valori letterali di stringa sono memorizzati in un pool comune. Ciò facilita la condivisione dell'archiviazione per stringhe con gli stessi contenuti per conservare l'archiviazione. Stringgli oggetti allocati tramite un nuovo operatore vengono archiviati in heap, e non esiste condivisione dello spazio di archiviazione per gli stessi contenuti.


72
Si noti che il "pool comune" in genere fa parte dell'heap.
Joachim Sauer,

3
@JoachimSauer Sì..con piccoli vantaggi :) aggiunto che nella nota.Grazie per il ricordo.
Suresh Atta,

2
Quindi è più veloce scrivere String s1 = "Hello"; di String s2 = new String ("Hello") ;?
user2097804

28
Aggiungo che nel tuo esempio s1 == s2 == s3 ma s4! = S5
Alfredo Osorio,

8
@AndrewJanke sul recente hotspot jvm (7), il pool di stringhe non è in perm gen e da Java 8 non ci sono più perm gen ...
assylias

50

Java considera String come una classe speciale, che puoi inizializzare in entrambi i modi

  1. Assegnazione diretta letterale

    String a = "adsasdf";
  2. Come altri oggetti che usano una nuova parola chiave

    String a = new String("adsasdf");

È necessario prestare particolare attenzione quando si desidera confrontare con il ==segno:

String a = "asdf";
String b = "asdf";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True

String a = new String("asdf");
String b = new String("asdf");
System.out.println(a == b);  // False
System.out.println(a.equals(b)); // True

Questo perché nel primo caso gli oggetti aeb vengono mantenuti in qualcosa chiamato literal pool ed entrambi fanno riferimento allo stesso oggetto, quindi sono uguali in entrambi i modi.

Ma nel secondo caso aeb fanno riferimento a diversi oggetti come quando inizializziamo qualsiasi altro oggetto. quindi sono disuguali se confrontati con l' ==operatore mentre sono uguali in valori.


18

La stringa riceve un trattamento speciale nel JLS: è uno dei due tipi non primitivi per i quali esistono letterali (l'altro è Class) * .

Dal JLS :

Un letterale stringa è un riferimento a un'istanza della classe `String [...].

* beh, c'è anche il "tipo null" con il suo "valore letterale null" null, ma la maggior parte delle persone non pensa al "tipo null" come a un tipo corretto.


1
Inoltre non ero a conoscenza del fatto che il "tipo null" è un tipo corretto in Java. Le sue informazioni molto utili, dovresti aumentare la dimensione del carattere.
Grijesh Chauhan,

1
@GrijeshChauhan: beh, il "tipo null" è solo una formulazione ingegnosa per consentire a chiunque nulldi essere assegnato a qualsiasi variabile del tipo di riferimento. Non è un tipo interessante, altrimenti.
Joachim Sauer,

15

È una caratteristica del linguaggio Java. Ai letterali di stringa nel codice sorgente viene assegnato un trattamento speciale.

Le specifiche del linguaggio, qui , dicono semplicemente che un letterale stringa è di Stringtipo


5

Il testo tra virgolette doppie crea un Stringoggetto letterale .

String myString = "Some text";

Il codice sopra crea un Stringoggetto, usando le doppie virgolette.


4

Le stringhe sono molto spesso utilizzate in un linguaggio di programmazione. Poiché java è orientato agli oggetti, una stringa è un oggetto. Per evitare la nuova ingombrante String ("someString"); ogni volta che hai bisogno di un oggetto stringa java ti permette di creare un oggetto stringa usando il valore letterale stringa.

Ma dovresti tenere presente l'uguaglianza delle stringhe. Ecco un breve test JUnit per dimostrare cosa intendo.

    @Test
    public void stringTest() {
       // a string literal and a string object created 
       // with the same literal are equal
       assertEquals("string", new String("string"));

       // two string literals are the same string object
       assertSame("string", "string"); 

       // a string literal is not the same object instance 
       // as a string object created with the same string literal
       assertFalse("string" == new String("string"));

       // java's String.intern() method gives you the same
       // string object reference for all strings that are equal.
       assertSame("string", new String("string").intern());
    }

Se potessi solo inizializzare una stringa con new String(String src), allora non potresti nemmeno dare al costruttore una stringa letterale. Dovresti inizializzare un char []e quindi usare il String(char [] src)coscruttore per costruire la stringa, altrimenti dovresti leggere la stringa da un file.
AJMansfield,

Questo non è corretto Un letterale stringa è solo una sequenza di caratteri in un file sorgente generato da virgolette doppie. Java crea automaticamente un'istanza di una stringa usando questo valore letterale. Pertanto un oggetto letterale e uno String sono uguali, ma non sono gli stessi. Java potrebbe anche essere implementato in questo modo che è necessario utilizzare il nuovo String (""); istanziare un oggetto String, ma questo renderebbe la nostra vita più dura. Pertanto, quando si scrive una nuova stringa ("una stringa") java crea un oggetto String per il letterale "una stringa" e passa questo oggetto stringa al costruttore della nuova stringa.
René Link,

2

Solo per citare. Un letterale a string è un riferimento a un'istanza della classe String che puoi scrivere in questo modo:

 .getBytes "ABC" ();

 "A: b: c" .split ( ":");

 "愛" .codePointAt (0);

2

- String è una classe in Java . Hai ragione, quindi possiamo sempre inizializzare con la newparola chiave.

- Ma quando facciamo qualcosa del genere:

String s = "";

L'istruzione precedente è contrassegnata dal compilatore come un oggetto String speciale e quindi JVM durante il caricamento della classe (il caricamento viene eseguito prima dell'inizializzazione), vede ciò che è noto come letterale stringa , che viene archiviato in un pool letterale stringa .

- Quindi una stringa può essere creata usando new()e con il ""metodo, ma quest'ultima fornisce una stringa letterale che rimane nell'heap anche quando non c'è alcun riferimento a quell'oggetto stringa, perché ha un riferimento dal pool letterale stringa.


2

Java esegue un processo in due fasi per noi.

String str = "hello";

è equivalente a

char data[] = {'h', 'e', 'l' , 'l', 'o'};
String str = new String(data);

Come [.NET] [1] ha ottenuto una cosa simile.

String(Char[]) constructor

fa

String(char[] value)

Aggiunta di riferimenti: -


2
Il processo che descrivi non è ciò che Java fa effettivamente: come altri hanno già affermato, "hello"è una stringa letterale e verrà inserita nel pool costante dal compilatore, vedi JLS §3.10.5 e JVMS §5.1 .
siegi,

1

Java.lang.Stringnon è solo una classe. È parte integrante del linguaggio principale. Il compilatore ha zucchero sintattico per questo. Ad esempio, ""è come un'abbreviazione per new String(""). Quando è scritto, ""il compilatore ottimizza stringhe identiche nella stessa istanza per risparmiare spazio."a" + 5 == "a5" ==> true

Il compilatore ha zucchero sintattico per molte cose, incluso il non dover box / unbox tra le versioni degli oggetti e i loro tipi nativi, nessun genitore significa Oggetto, costruttore predefinito, ...


5
""non è un'abbreviazione di new String(""). Se lo usi "", la prima cosa da fare è cercare le corrispondenze nel pool di stringhe della JVM e, se questo è vero, restituirà quella stringa. Usando new String(""), creerai sempre una nuova stringa, anche se la stringa stessa esiste già nel pool di stringhe (perché non verrà memorizzata nel pool di stringhe).
g00glen00b,

Ho aggiornato la mia risposta. Le persone lo usano a proprio vantaggio, come usare costanti di stringa equivalenti al tipo di simbolo Lisp?
Sylwester,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.