Come può essere inizializzata una stringa usando “”?

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

La stringa Java è speciale

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

Per motivi di prestazioni, Java’s String è progettato per essere tra una primitiva e una class.

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 la descrizione dell'immagine qui

Nota: i valori letterali stringa sono memorizzati in un pool comune. Ciò facilita la condivisione dello storage per stringhe con lo stesso contenuto per risparmiare spazio. String oggetti String allocati tramite un nuovo operatore sono archiviati heap e non vi è alcuna condivisione di archiviazione per lo stesso contenuto.

Java considera String come una class speciale, è ansible inizializzarla in entrambi i modi

  1. Assegnazione diretta letterale

     String a = "adsasdf"; 
  2. Come altri oggetti che utilizzano 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 a e b sono mantenuti in qualcosa chiamato literal pool e entrambi fanno riferimento allo stesso object in modo che siano uguali in entrambi i modi.

Ma nel secondo caso a e b fanno riferimento a oggetti diversi come quando inizializziamo qualsiasi altro object. quindi sono disuguali rispetto all’operatore == mentre sono uguali nei valori.

String ottiene un trattamento speciale in JLS: è uno dei due tipi non primitivi per cui esistono letterali (l’altro è Class ) * .

Dalla JLS :

Una stringa letterale è un riferimento a un’istanza di class `String […].

* beh, c’è anche il “tipo nullo” con il suo valore “null literal” null , ma la maggior parte delle persone non pensa al “tipo nullo” come a un tipo corretto.

È una funzionalità del linguaggio Java. I valori letterali delle stringhe nel codice sorgente ricevono un trattamento speciale.

La specifica della lingua, qui , dice semplicemente che una stringa letterale è di tipo String

Il testo tra virgolette crea un object String letterale.

 String myString = "Some text"; 

Il codice sopra crea un object String , usando virgolette doppie.

Le stringhe sono spesso utilizzate in un linguaggio di programmazione. Poiché java è orientato agli oggetti, una stringa è un object. Per evitare l’ingombrante nuova String (“someString”); dichiarazione ogni volta che hai bisogno di un object stringa java ti permette di creare semplicemente un object stringa usando la stringa letterale.

Ma dovresti tenere a mente 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()); } 

Solo per citare Una stringa letterale è un riferimento a un’istanza della class String che è ansible scrivere in questo modo:

  .getBytes "ABC" ();

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

  "愛" .codePointAt (0);

String è una class in Java . Hai ragione, quindi possiamo sempre inizializzare con la new parola chiave.

Ma quando facciamo qualcosa come:

String s = "";

L’istruzione precedente è contrassegnata dal compilatore come object String speciale e quindi JVM durante il caricamento della class (il caricamento viene eseguito prima dell’inizializzazione), ciò che viene chiamato letterale stringa , che viene archiviato in un lotto 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’è riferimento a quell’object stringa, perché ha un riferimento dalla stringa letterale piscina.

Java fa 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: –

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

Il compilatore ha zucchero sintattico per un sacco di cose, incluso non dover box / unbox tra le versioni degli oggetti ei loro tipi nativi, nessun genitore significa Object, costruttore predefinito, …