128 votes

Comment fonctionne la classe String surcharger l'opérateur+?

Pourquoi en Java, vous êtes en mesure d'ajouter des Chaînes de caractères avec l'opérateur+, quand la Chaîne est une classe? Dans l'String.java code je n'ai pas trouvé de mise en œuvre de cet opérateur. Ce concept de violer l'orientation de l'objet?

155voto

Lion Points 7328

Regardons la suite des expressions simples en Java

int x=15;
String temp="x = "+x;

Le compilateur convertit "x = "+x; en StringBuilder à l'interne et utilise .append(int) "ajouter" l'entier de la chaîne.

5.1.11. Conversion De Chaîne De Caractères

N'importe quel type peut être converti en type de Chaîne par chaîne de conversion.

Une valeur x de la primitive de type T est d'abord convertie en une valeur de référence comme si en lui donnant comme argument une instance de classe la création de l'expression (§15.9):

  • Si T est de type boolean, puis utilisez Boolean(x).
  • Si T est de type char, puis utilisez de nouveau Personnage(x).
  • Si T est le byte, short, int, puis utilisez new Integer(x).
  • Si T est long, l'utilisation de nouvelles Long(x).
  • Si T est float, puis utilisez nouveau Float(x).
  • Si T est double, puis utilisez nouveau Double(x).

Cette valeur de référence est ensuite convertie en Chaîne de type string la conversion.

Maintenant, seules les valeurs de référence doivent être considérés:

  • Si la référence est nulle, il est converti en chaîne de la valeur "null" (quatre caractères ASCII n, u, l, l).
  • Sinon, la conversion est effectuée comme si par un appel de la méthode toString de l'objet référencé sans arguments; mais si le résultat de l'invocation de la méthode toString est nulle, alors la la chaîne de la valeur "null" est utilisé à la place.

La méthode toString est défini par le primordial de la classe de l'Objet (§4.3.2). De nombreuses classes de la remplacer, notamment Booléen, Caractère, Integer, Long, Float, Double, et de la Corde.

Voir §5.4 pour plus de détails de la chaîne de conversion de contexte.

15.18.1.

L'optimisation de la Concaténation de Chaîne : Une mise en œuvre peut choisir d'effectuer la conversion et de la concaténation en une seule étape pour éviter de créer puis de jeter un intermédiaire Objet de type String. Pour augmenter le rendement de la répétition de la chaîne de concaténation, d'un compilateur Java peut utiliser la classe StringBuffer ou un technique similaire pour réduire le nombre des intermédiaires de la Chaîne objets qui sont créés par l'évaluation d'une expression.

Pour les types primitifs, une mise en œuvre peut également optimiser loin de la création d'un objet wrapper en convertissant directement à partir d'une primitive type de chaîne.

La version optimisée ne sera pas réellement faire un plein gainé de conversion de Chaîne de caractères en premier.

C'est une bonne illustration d'une version optimisée pour être utilisée par le compilateur, mais sans la conversion d'une primitive, où vous pouvez voir le compilateur de changer les choses dans un StringBuilder en arrière-plan:

http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/


Ce code java:

public static void main(String[] args) {
    String cip = "cip";
    String ciop = "ciop";
    String plus = cip + ciop;
    String build = new StringBuilder(cip).append(ciop).toString();
}

Génère cette - voir comment la concaténation de deux styles de conduire à la même bytecode:

 L0
    LINENUMBER 23 L0
    LDC "cip"
    ASTORE 1
   L1
    LINENUMBER 24 L1
    LDC "ciop"
    ASTORE 2

   // cip + ciop

   L2
    LINENUMBER 25 L2

    NEW java/lang/StringBuilder
    DUP
    ALOAD 1
    INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
    INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

    ASTORE 3

    // new StringBuilder(cip).append(ciop).toString()

   L3
    LINENUMBER 26 L3

    NEW java/lang/StringBuilder
    DUP
    ALOAD 1
    INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;

    ASTORE 4
   L4
    LINENUMBER 27 L4
    RETURN

En regardant l'exemple ci-dessus, et comment l'octet de code basé sur le code source de l'exemple donné est généré, vous serez en mesure d'avis que le compilateur a l'interne transformé la déclaration suivante

cip+ciop; 

en

new StringBuilder(cip).append(ciop).toString();

En d'autres termes, l'opérateur + dans la concaténation de chaîne est effectivement un raccourci pour la plus prolixe StringBuilder idiome.

27voto

Ramesh PVK Points 7415

C'est un compilateur Java fonction qui vérifie les opérandes d' + de l'opérateur. Et sur la base des opérandes il génère le code octet:

  • Pour la Chaîne, il génère du code de la concaténation de chaînes de caractères
  • Pour les Nombres, il génère du code pour ajouter des numéros.

C'est ce que le Java spec dit:

Les opérateurs + et - sont appelés les additifs opérateurs. AdditiveExpression: MultiplicativeExpression AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression

L'additif opérateurs ont la même priorité et sont syntaxiquement associativité à gauche (ils de groupe de gauche à droite). Si le type de opérande d'un + de l'opérateur est - String, alors l'opération de concaténation de chaîne.

Autrement, le type de chacun des opérandes de l' + de l'opérateur doivent être d'un type qui est convertible (§5.1.8)à une primitive de type numérique, ou une erreur de compilation se produit.

Dans tous les cas, le type de chacun des opérandes de l'binaire - opérateur doit être un type qui est convertible (§5.1.8) à une primitive de type numérique, ou un erreur de compilation se produit.

14voto

EJP Points 113412

Comment la classe String remplace opérateur+?

Il n'a pas. Le compilateur ne. Strictement parlant, le compilateur les surcharges de l'opérateur + pour la Chaîne d'opérandes.

6voto

Pramod Kumar Points 3682
First of all (+) is overloaded not overridden 

Le langage Java fournit un soutien spécial pour la chaîne l'opérateur de concaténation (+), qui a été surchargé pour les Cordes de Java objets.

1) Si gauche opérande est une Chaîne, il fonctionne comme la concaténation.

2) Si gauche opérande est de type Entier, il travaille comme opérateur d'addition

4voto

alexis Points 10856

Le sens de l' + de l'opérateur lorsqu'il est appliqué à l' String est défini par la langue, comme tout le monde a déjà écrit. Puisque vous ne semblez pas trouver suffisamment convaincante, considérez ceci:

Ints, des flotteurs et des doubles ont tous différents les représentations binaires, et donc l'ajout de deux entiers est une autre opération, en termes de manipulation de bits, que l'ajout de deux flotteurs: Pour les services de renseignements vous pouvez ajouter peu à peu, la réalisation un peu et de contrôle pour le trop-plein; pour des flotteurs vous devez traiter la mantissas et les exposants séparément.

Donc, en principe, "plus" dépend de la nature des objets ", a ajouté". Java définit pour les Chaînes ainsi que des entiers et des flottants (long, double, ...)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X