2010-02-24 3 views
7

Ho visto this question alcuni minuti fa e ho deciso di dare un'occhiata alla classe java String per verificare se ci fosse un sovraccarico per l'operatore +.+ operatore per String in Java

io non ho trovato nulla, ma so che posso fare questo

String ab = "ab"; 
String cd = "cd"; 
String both = ab + cd; //both = "abcd" 

Dov'è che ha implementato?

risposta

12

Dal Fine Manual:

Il linguaggio Java fornisce un supporto speciale per l'operatore di concatenazione di stringhe (+), e per la conversione di altri oggetti in stringhe. La concatenazione di stringhe viene implementata tramite la classe StringBuilder (o StringBuffer) e il suo metodo append. Le conversioni di stringhe vengono implementate tramite il metodo toString, definito da Object ed ereditato da tutte le classi in Java. Per ulteriori informazioni sulla concatenazione e conversione delle stringhe, vedere Gosling, Joy e Steele, La specifica del linguaggio Java.

Vedere String Concatenation nel JLS.

+0

'StringBuilder' dovrebbe essere preferito quando la sincronizzazione non è un problema. – gpampara

+0

@gpampara Il compilatore sa usare StringBuilder. StringBuffer è stato utilizzato nelle vecchie versioni prima dell'introduzione di StringBuilder. –

2

Viene gestito dal compilatore.

+1

Risposta impressionante. Hai considerato di essere un insegnante? – whiskeysierra

+0

@Willi Schönborn: Beh, è ​​la risposta semplice e corretta. Non ho avuto il tempo di scrivere di più quando l'ho scritto e quando sono tornato al computer c'erano molte risposte che lo spiegavano in modo più dettagliato. Mi spiace dirlo, ma non vedo il punto nel duplicare le altre risposte, consiglio di leggere @ Sean e @ jleedev's se hai bisogno di maggiori informazioni (E sì, l'insegnamento è sul mio curriculum). – Fredrik

+0

Il punto è: la tua risposta è così generale, che si adatta per quasi il 75% di tutte le domande relative a Java su SO. – whiskeysierra

2

Questo comportamento speciale è documentato nello language specification.

15.18.1 stringa di concatenazione Operatore +

Se solo un'espressione operando è di tipo String , quindi conversione stringa viene eseguita dall'altro operando produrre una stringa in fase di esecuzione. Il risultato è un riferimento a un oggetto String (appena creata, a meno che l'espressione è una fase di compilazione costante espressione (§15.28)), che è il concatenazione dei due operandi stringhe. I caratteri dell'operando a sinistra precedono i caratteri dell'operando di destra nella stringa appena creata. Se un operando di tipo String è null, allora viene utilizzata la stringa "null" anziché tale operando.

7

Il compilatore tratta i il codice come se avessi scritto qualcosa del tipo:

String both = new StringBuilder().append(ab).append(cd).toString(); 

Edit: Qualsiasi riferimento? Bene, se compilo e decompilo il codice dell'OP, ottengo questo:

0: ldC#2; //String ab 
2: astore_1 
3: ldC#3; //String cd 
5: astore_2 
6: new #4; //class java/lang/StringBuilder 
9: dup 
10: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V 
13: aload_1 
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
17: aload_2 
18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
21: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
24: astore_3 
25: return 

Quindi, è come ho detto.

+1

qualche riferimento per questo? –

0

String è definito come un tipo standard proprio come int, double, float, ecc. A livello di compilatore. In sostanza, tutti i compilatori hanno un sovraccarico dell'operatore. L'overloading dell'operatore non è definito per gli sviluppatori (a differenza di C++).

È interessante notare che: La domanda è stata registrata come un bug: http://bugs.sun.com/view_bug.do?bug_id=4905919

2

La maggior parte delle risposte qui sono corrette (è gestito dal compilatore, + viene convertito in .Append() ...)

Volevo aggiungere che tutti dovrebbero dare un'occhiata al codice sorgente di String e append ad un certo punto, è piuttosto impressionante.

credo è venuto giù a qualcosa di simile:

"a"+"b"+"c" 

=

new String().append("a").append("b").append("c") 

Ma poi qualcosa di magico accade. Questo diventa:

  • creare una matrice stringa di lunghezza 3
  • copia una nella prima posizione.
  • copia b nella seconda
  • copy c nel terzo

Mentre la maggior parte delle persone credono che creerà "ab", poi gettarlo via quando si crea "abc". In realtà capisce che è incatenato e fa qualche manipolazione.

C'è anche un trucco in cui se si ha la stringa "abc" e si richiede una sottostringa che risulta essere "bc", possono condividere lo stesso array sottostante. Noterai che c'è una posizione iniziale, una posizione finale e un flag "condiviso".

Infatti, se non è condiviso, è possibile per poter estendere la lunghezza di una stringa e copiare gli altri in.

Ora sto solo di essere fonte di confusione. Leggi il codice sorgente: è abbastanza bello.

+1

Non c'è 'new String(). Append (" a "). Append (" b "). Append (" c ")', ma 'new StringBuilder(). Append (" a "). Append (" b) .append ("c"). toString() '. Il modo * no-stringbuilder * sarebbe' "a" .concat ("b"). concat ("c") ', e questo è il modo inefficiente come hai descritto. (Ma quando si usa + con costanti in fase di compilazione, tutto questo è già fatto dal compilatore.) –