2010-02-24 8 views
7

J'ai vu this question il y a quelques minutes, et j'ai décidé de jeter un oeil dans la classe java String pour vérifier s'il y avait une surcharge pour l'opérateur +.+ opérateur pour String en Java

je ne pouvais pas trouver quoi que ce soit, mais je sais que je peux le faire

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

Où est cette mise en œuvre?

Répondre

12

De l'Fine Manual:

Le langage Java fournit un support spécial pour l'opérateur de concaténation (+), et pour la conversion d'autres objets à cordes. La concaténation de chaîne est implémentée via la classe StringBuilder (ou StringBuffer) et sa méthode append. Les conversions de chaînes sont implémentées via la méthode toString, définie par Object et héritée par toutes les classes de Java. Pour plus d'informations sur la concaténation et la conversion de chaînes, voir Gosling, Joy et Steele, La spécification de langage Java.

Voir String Concatenation dans le fichier JLS.

+0

'StringBuilder' devrait être préféré lorsque la synchronisation n'est pas un problème. – gpampara

+0

@gpampara Le compilateur sait utiliser StringBuilder. StringBuffer a été utilisé dans les anciennes versions avant l'introduction de StringBuilder. –

2

Il est géré par le compilateur.

+1

Réponse impressionnante. Avez-vous envisagé d'être un enseignant? – whiskeysierra

+0

@Willi Schönborn: Eh bien, c'est la réponse simple et correcte. Je n'ai pas eu le temps d'écrire plus quand je l'ai écrit et quand je suis revenu à l'ordinateur il y avait beaucoup de réponses l'expliquant plus en détail. Désolé de le dire, mais je ne vois pas l'intérêt de dupliquer les autres réponses, je vous recommande de lire @ Sean's et @ jleedev si vous avez besoin de plus d'infos (Et oui, l'enseignement est sur mon CV). – Fredrik

+0

Le point est: Votre réponse est si générale, elle correspond à presque ~ 75% de toutes les questions relatives à Java sur SO. – whiskeysierra

2

Ceci est un comportement spécial documenté dans language specification.

15.18.1 opérateur + Concaténation

Si une seule expression d'opérande est de de type String, puis la conversion de chaîne est réalisée sur l'autre opérande à produire une chaîne au moment de l'exécution. Le résultat est une référence à une chaîne de caractères objet (nouvellement créé, à moins que l'expression est une compilation expression constante (§15.28)) qui est la concaténation des deux opérandes chaînes. Les caractères de l'opérande gauche précèdent les caractères de l'opérande droit dans la chaîne nouvellement créée. Si un opérande de type String est nul, alors la chaîne "null" est utilisée à la place de cet opérande.

7

Le compilateur traite votre code comme si vous aviez écrit quelque chose comme:

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

Edit: Toute référence? Eh bien, si je compile et décompiler le code de l'OP, je reçois ceci:

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 

Ainsi, il est comme je l'ai dit.

+1

une référence pour cela? –

0

String est défini comme un type standard, tout comme int, double, float, etc. au niveau du compilateur. Essentiellement, tous les compilateurs ont une surcharge de l'opérateur. La surcharge de l'opérateur n'est pas définie pour les développeurs (contrairement à C++).

assez intéressant: Cette question a été enregistrée comme un bug: http://bugs.sun.com/view_bug.do?bug_id=4905919

2

La plupart des réponses ici sont correctes (il est géré par le compilateur, + est converti en .append() ...)

Je voulais ajouter que tout le monde devrait jeter un oeil au code source de String et ajouter à un moment donné, c'est assez impressionnant.

je crois qu'il est descendu à quelque chose comme:

"a"+"b"+"c" 

=

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

Mais quelque chose de magique se produit. Cela se transforme en:

  • Créer un tableau de chaînes de longueur 3
  • copie un dans la première position.
  • copie b dans la deuxième
  • copie c dans le troisième

Alors que la plupart des gens croient que cela va créer « ab », puis le jeter quand il crée « abc ». Il comprend en fait qu'il est enchaîné et qu'il fait des manipulations.

Il y a aussi un truc où si vous avez la chaîne "abc" et que vous demandez une sous-chaîne qui s'avère être "bc", ils peuvent partager exactement le même tableau sous-jacent. Vous remarquerez qu'il y a une position de départ, une position de fin et un drapeau "partagé".

En fait, si ce n'est pas partagé, il est possible qu'elle prolonger la longueur d'une chaîne et copier les autres dans.

Maintenant, je suis juste confus. Lisez le code source - c'est plutôt cool.

+1

Il n'y a pas de nouvelle chaîne(). Append ("a"). Append ("b"). Append ("c") ', mais' new StringBuilder(). Append ("a"). Append ("b) .append ("c"). toString() '. La méthode * no-stringbuilder * serait' "a" .concat ("b"). concat ("c") ', et c'est la méthode inefficace vous l'avez décrit. (Mais lorsque vous utilisez + avec des constantes de compilation, tout ceci est déjà fait par le compilateur.) –