En Java, es el resultado de la adición de dos caracteres un int o un char?


Al agregar 'a' + 'b' produce 195. ¿Es el tipo de datos de salida char o int?

Author: vaxquis, 2011-12-31

8 answers

El resultado de agregar caracteres Java, cortocircuitos o bytes es un int :

Especificación del Lenguaje Java sobre Promoción Numérica Binaria :

  • Si alguno de los operandos es de un tipo de referencia, la conversión de unboxing (§5.1.8). Entonces:
  • Si cualquiera de los operando es de tipo double, el otro se convierte en doble.
  • De lo contrario, si cualquiera de los operando es de tipo flotar, el otro se convierte en flotar.
  • De lo contrario, si cualquiera de los operando es de tipo largo, el otro se convierte en largo.
  • De lo contrario, ambos los operandos se convierten al tipo int.

Pero tenga en cuenta lo que dice sobre los operadores de asignación compuesta (como +=):

El resultado de la operación binaria se convierte al tipo de la variable izquierda ... y el resultado de la conversión se almacena en la variable.

Por ejemplo:

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

Una forma de encontrar el tipo del resultado, en general, es lanzarlo a un Objeto y preguntarle qué clase es:

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

Si está interesado en el rendimiento, tenga en cuenta que el bytecode Java ni siquiera tiene instrucciones dedicadas para la aritmética con los tipos de datos más pequeños. Por ejemplo, para agregar, hay instrucciones iadd (para ints), ladd (para longs), fadd (para floats), dadd (para doubles), y eso es todo. Para simular x += y con los tipos más pequeños, el compilador utilizará iadd y luego pon a cero los bytes superiores de la int usando una instrucción como i2c ("int to char"). Si la CPU nativa tiene instrucciones dedicadas para datos de 1 byte o 2 bytes, depende de la máquina virtual Java optimizar para eso en tiempo de ejecución.

Si desea concatenar caracteres como una cadena en lugar de interpretarlos como un tipo numérico, hay muchas maneras de hacerlo. Lo más fácil es agregar una cadena vacía a la expresión, porque agregar un carácter y una cadena resulta en una cadena. Todos estos las expresiones dan como resultado la cadena "ab":

  • 'a' + "" + 'b'
  • "" + 'a' + 'b' (esto funciona porque "" + 'a' se evalúa primero; si el "" estuviera al final, obtendrías "195")
  • new String(new char[] { 'a', 'b' })
  • new StringBuilder().append('a').append('b').toString()
  • String.format("%c%c", 'a', 'b')
 112
Author: Boann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-26 01:43:45

Las operaciones aritméticas binarias en char y byte (y short) promueven a int J JLS 5.6.2.

 19
Author: Hot Licks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-31 14:40:28

Puede que desee aprender las siguientes expresiones acerca de char.

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

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

Esto es perfectamente válido en Java y devuelve 66, el valor correspondiente del carácter (Unicode) de c+1.


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

Esto es demasiado válido en Java y la variable de tipo String temp acepta automáticamente c de tipo char y produce temp=A en la consola.


¡Todas las siguientes instrucciones también son válidas 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);

Aunque c es un tipo de char, se puede suministrar sin error en los constructores respectivos y todas las instrucciones anteriores se tratan como instrucciones válidas. Producen los siguientes productos respectivamente.

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

char es un tipo integral numérico primitivo y como tal está sujeto a todas las reglas de estas bestias incluyendo conversiones y promociones. Usted querrá leer sobre esto, y el JLS es una de las mejores fuentes para esto: Conversiones y Promociones. En particular, lea el fragmento corto on "5.1.2 Widening Primitive Conversion".

 6
Author: Lion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-31 15:20:50

El compilador Java puede interpretarlo como cualquiera de los dos.

Compruébelo escribiendo un programa y buscando errores de compilador:

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

Si es un char, entonces la primera línea me dará un error y la segunda no. Si es un int, entonces sucederá lo contrario.

Lo compilé y lo conseguí..... SIN ERRORES. Así que Java acepta ambos.

Sin embargo, cuando los imprimí, obtuve:

Int: 195

Char: Ã

Lo que sucede es que cuando lo haces:

char result2 = 'a' + 'b'

Se realiza una conversión implícita (una "conversión de estrechamiento primitivo" de int a char).

 3
Author: eboix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-31 15:55:40

De acuerdo con las reglas de promoción binaria , si ninguno de los operandos es doble, flotante o largo, ambos se promueven a int. Sin embargo, aconsejo fuertemente en contra de tratar el tipo char como numérico, que tipo de derrota su propósito.

 2
Author: Sergei Tachenov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-31 14:41:47

Si bien ya tiene la respuesta correcta (referenciada en el JLS), aquí hay un poco de código para verificar que obtiene un int al agregar dos chars.

public class CharAdditionTest
{
    public static void main(String args[])
    {
        char a = 'a';
        char b = 'b';

        Object obj = a + b;
        System.out.println(obj.getClass().getName());
    }
}

La salida es

Java.lang.Integer

 1
Author: Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-31 16:01:58

char se representa como Unicode valores y donde los valores Unicode están representados por \u, seguido por Hexadecimal valores.

Como cualquier operación aritmética en char valores promovidos a int, por lo que el resultado de 'a' + 'b' se calcula como

1.) Aplicar los valores Unicode al char correspondiente usando Unicode Table

2.) Aplicar la conversión Hexadecimal a Decimal y luego realizar la operación en Decimal valor.

    char        Unicode      Decimal
     a           0061          97
     b           0062          98  +
                              195

Unicode To Decimal Converter

Ejemplo

0061

(0*163) + (0*162) + (6*161) + (1*160)

(0*4096) + (0*256) + (6*16) + (1*1)

0 + 0 + 96 + 1 = 97

0062

(0*163) + (0*162) + (6*161) + (2*160)

(0*4096) + (0*256) + (6*16) + (2*1)

0 + 0 + 96 + 2 = 98

Por lo tanto 97 + 98 = 195


Ejemplo 2

char        Unicode      Decimal
 Ջ           054b         1355
 À           00c0          192 
                      --------
                          1547    +
                          1163    -
                             7    /
                        260160    *
                            11    %
 1
Author: Pavneet_Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-03 15:08:15

Aquí hay algo extraño, sin embargo. Los siguientes compiles:

char x;
x = 'a' + 'b';

Pero esto no:

char x;
x = 'a';
x = x + 'b';

Parece que ambas expresiones ('a'+' b'y x+' b') resultan en enteros, mediante la siguiente prueba:

Object obj = 'a'+'b';
System.out.println(obj.getClass().getName());

char x = 'a';
Object obj2 = x+'b';
System.out.println(obj2.getClass().getName());

Entonces, ¿por qué el segundo caso no compila? Por cierto, puede arreglarlo lanzando toda la expresión como un char:

x = (char)(x+'b');

Esto parece una inconsistencia en la semántica de Java-cualquier expresión char debe ser intercambiable con otra en cualquier contexto. ¿Alguien sabe cómo darle sentido a esto?

 0
Author: Sam Scott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-16 17:07:22