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?
Réponses
Trop de publicités?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.
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.
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 - MultiplicativeExpressionL'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.
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
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, ...)