89 votes

En Java, le résultat de l'ajout de deux caractères est-il un entier ou un caractère?

En ajoutant 'a' + 'b' il en résulte 195.

J'ai demandé sur le canal IRC StackOverflow qu'ils disaient que le type de données de sortie était char. Je pense que c'est int, et d'autres aussi.

Quelle est la bonne réponse?

141voto

Boann Points 11904

Le résultat de l'ajout de Java chars, des shorts ou des octets est un int:

Java Langage de Spécification sur Binaire Numérique de la Promotion:

  • Si l'un des opérandes est de type référence, unboxing de conversion (§5.1.8) est effectuée. Alors:
  • Si l'un des deux opérandes est de type double, le autre est converti en double.
  • Sinon, si l'un des deux opérandes est de type float, l'autre est converti en float.
  • Sinon, si l'un des deux opérandes est de type long, l'autre est converti en long.
  • Sinon, les deux les opérandes sont convertis en type int.

Mais notez ce qu'il dit à propos de composé des opérateurs d'affectation (+=):

Le résultat de l'opération binaire est converti dans le type de la gauche de la variable ... et le résultat de la conversion est stockée dans la variable.

Par exemple:

char x = 1, y = 2;
x = x + y; // compile error: "possible loss of precision (found int, required char)"
x = (char)(x + y); // explicit cast back to char; OK
x += y; // compound operation-assignment; also OK

Une façon, vous pouvez trouver le type de résultat, en général, est de lancer à un Objet et de lui demander dans quelle classe il est:

System.out.println(((Object)('a' + 'b')).getClass());
// outputs: class java.lang.Integer

Si vous êtes intéressé par la performance, notez que le bytecode Java ne dispose même pas d'dédié instructions pour l'arithmétique avec les plus petits types de données. Par exemple, pour ajouter, il y a des instructions iadd (pour les entiers), ladd (pour les longs), fadd (pour les chars), dadd (pour les doubles), et c'est tout. Pour simuler x += y avec les plus petits types, le compilateur utilisera iadd , puis zéro la partie supérieure octets de l'int à l'aide de l'instruction i2c ("int en char"). Si le natif du PROCESSEUR a consacré instructions pour 1 octet ou de données de 2 octets, c'est à la machine virtuelle Java pour optimiser pour qu'au moment de l'exécution.

Si vous voulez concaténer des caractères d'une Chaîne plutôt que de les interpréter comme un type numérique, il y a beaucoup de façons de le faire. Le plus simple est d'ajouter une Chaîne vide à l'expression, car l'ajout d'un char et d'une Chaîne de résultats dans une Chaîne de caractères. Toutes ces expressions résultat dans la Chaîne "ab":

  • 'a' + "" + 'b'
  • "" + 'a' + 'b' (ceci fonctionne parce qu' "" + 'a' est évalué en premier; si l' "" l'étaient à la fin au lieu de cela, vous obtiendrez "195")
  • new String(new char[] { 'a', 'b' })
  • new StringBuilder().append('a').append('b').toString()
  • String.format("%c%c", 'a', 'b')

22voto

Hot Licks Points 25075

Les opérations arithmétiques binaires sur char et byte (et short ) passent à int - JLS 5.6.2.

7voto

Lion Points 7328

Vous pouvez apprendre les expressions suivantes à propos de char.

char c='A';
int i=c+1;

System.out.println("i = "+i);

C'est parfaitement valide en Java et les retours 66, la valeur correspondante de l'caractères (Unicode) c+1.


String temp="";
temp+=c;
System.out.println("temp = "+temp);

Ceci est aussi valable en Java et le type de Chaîne variable temp accepte automatiquement c de type char et produit temp=A sur la console.


Toutes les affirmations suivantes sont également valables en Java!

Integer intType=new Integer(c);
System.out.println("intType = "+intType);

Double  doubleType=new Double(c);
System.out.println("doubleType = "+doubleType);

Float floatType=new Float(c);
System.out.println("floatType = "+floatType);

BigDecimal decimalType=new BigDecimal(c);
System.out.println("decimalType = "+decimalType);

Long longType=new Long(c);
System.out.println("longType = "+longType);

Bien qu' c est un type d' char, elle peut être fournie avec aucune erreur dans les différents constructeurs et toutes les déclarations ci-dessus sont traités comme des instructions valides. Ils produisent les résultats suivants, respectivement.

intType = 65
doubleType = 65.0
floatType = 65.0
decimalType = 65
longType =65

char est une primitive intégrale de type et, comme telle, est soumis à toutes les règles de ces bêtes dont la conversion et les promotions. Vous aurez envie de lire sur ce, et le JLS est l'une des meilleures sources: les Conversions et les Promotions. En particulier, lire le peu court sur "5.1.2 l'Élargissement des Primitives de Conversion".

3voto

eboix Points 3072

Le compilateur Java peut l'interpréter comme l'un des deux.

Vérifier par l'écriture d'un programme et la recherche d'erreurs du compilateur:

public static void main(String[] args) {
    int result1 = 'a' + 'b';
    char result2 = 'a' + 'b';
}

Si c'est un char, puis la première ligne va me donner l'erreur et le second ne le sera pas. Si c'est un int, alors le contraire qui se produira.

J'ai compilé et j'ai eu..... PAS D'ERREURS. Donc Java accepte à la fois.

Cependant, lorsque j'ai imprimé, je l'ai eu:

int: 195

char: Ã

Ce qui se passe est que lorsque vous faites:

char result2 = 'a' + 'b'

une conversion implicite est faite (un "primitif conversion restrictive" de l' int de char).

1voto

Sergey Tachenov Points 8123

Selon les règles de promotion binaire , si aucun des opérandes n'est double, float ou long, les deux sont promus en int. Cependant, je déconseille vivement de considérer le type de caractère comme numérique, ce qui va à l’encontre de son objectif.

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