Cuando se agrega 'a' + 'b'
produce 195. ¿Es el tipo de datos de salida char
o int
?
Cuando se agrega 'a' + 'b'
produce 195. ¿Es el tipo de datos de salida char
o int
?
Respuestas:
El resultado de agregar caracteres, cortos o bytes de Java 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, se realiza la conversión de unboxing (§5.1.8). Luego:
- Si alguno de los operandos es de tipo double, el otro se convierte en double.
- De lo contrario, si alguno de los operandos es de tipo flotante, el otro se convierte en flotante.
- De lo contrario, si alguno de los operandos es de tipo long, el otro se convierte en long.
- De lo contrario, ambos 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 de la 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 averiguar el tipo de resultado, en general, es lanzarlo a un Objeto y preguntarle de 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 código de bytes de Java ni siquiera tiene instrucciones dedicadas para aritmética con los tipos de datos más pequeños. Por ejemplo, para sumar, hay instrucciones iadd
(para ints), ladd
(para largos), fadd
(para flotadores), dadd
(para dobles), y eso es todo. Para simular x += y
con los tipos más pequeños, el compilador usará iadd
y luego pondrá a cero los bytes superiores del 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 optimizarlas en tiempo de ejecución.
Si desea concatenar caracteres como una cadena en lugar de interpretarlos como un tipo numérico, hay muchas formas 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 da como resultado una cadena. Todas estas expresiones dan como resultado la Cadena "ab"
:
'a' + "" + 'b'
"" + 'a' + 'b'
(esto funciona porque "" + 'a'
se evalúa primero; si ""
estuvieran al final, obtendría "195"
)new String(new char[] { 'a', 'b' })
new StringBuilder().append('a').append('b').toString()
String.format("%c%c", 'a', 'b')
Las operaciones aritméticas binarias en char
y byte
(y short
) promueven a int
- JLS 5.6.2.
Es posible que desee aprender las siguientes expresiones sobre 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 el c
tipo char y produce temp=A
en la consola.
¡Todas las siguientes declaraciones 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 errores en los constructores respectivos y todas las declaraciones anteriores se tratan como declaraciones válidas. Producen las siguientes salidas 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, incluidas las conversiones y promociones. Querrá leer más sobre esto, y JLS es una de las mejores fuentes para esto: conversiones y promociones . En particular, lea el breve fragmento sobre "5.1.2 Ampliación de la conversión primitiva".
El compilador de Java puede interpretarlo como cualquiera.
Compruébelo escribiendo un programa y buscando errores del compilador:
public static void main(String[] args) {
int result1 = 'a' + 'b';
char result2 = 'a' + 'b';
}
Si es un carácter, entonces la primera línea me dará un error y la segunda no. Si es un int, entonces sucederá lo contrario.
Lo compilé y obtuve ..... NO ERRORES. Entonces Java acepta ambos.
Sin embargo, cuando los imprimí, obtuve:
int: 195
char: Ã
Lo que pasa es que cuando lo haces:
char result2 = 'a' + 'b'
se realiza una conversión implícita (una "conversión de restricción primitiva" de int a char ).
De acuerdo con las reglas de promoción binaria , si ninguno de los operandos es double, float o long, ambos se promocionan a int. Sin embargo, recomiendo encarecidamente no tratar el tipo char como numérico, ya que eso frustra su propósito.
char
como valor numérico está completamente dentro de su propósito, por lo que JLS dedica tanta verborrea a dicho uso.
Si bien ya tiene la respuesta correcta (a la que se hace referencia en el JLS), aquí hay un poco de código para verificar que obtiene un int
al agregar dos char
s.
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
int
y Integer
no son lo mismo. Una verificación más convincente es intentar asignar a + b
a una int
variable o una char
variable. Este último da un error de compilación que dice en efecto "no se puede asignar una int
a una char
".
char
se representa como Unicode
valores y donde los valores Unicode se representan \u
seguido de Hexadecimal
valores.
Como cualquier operación aritmética sobre char
valores promovidos int
, el resultado de 'a' + 'b'
se calcula como
1.) Aplicar los Unicode
valores en el char
uso correspondienteUnicode Table
2.) Aplicar la conversión de hexadecimal a decimal y luego realizar la operación en Decimal
valores.
char Unicode Decimal
a 0061 97
b 0062 98 +
195
Ejemplo
0061
(0 * 16 3 ) + (0 * 16 2 ) + (6 * 16 1 ) + (1 * 16 0 )
(0 * 4096) + (0 * 256) + (6 * 16) + (1 * 1)
0 + 0 + 96 + 1 = 97
0062
(0 * 16 3 ) + (0 * 16 2 ) + (6 * 16 1 ) + (2 * 16 0 )
(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 %
Si bien la respuesta de Boann es correcta, existe una complicación que se aplica al caso de las expresiones constantes cuando aparecen en contextos de asignación .
Considere los siguientes ejemplos:
char x = 'a' + 'b'; // OK
char y = 'a';
char z = y + 'b'; // Compilation error
Que esta pasando? Quieren decir lo mismo, ¿no? ¿Y por qué es legal asignar un int
a char
en el primer ejemplo?
Cuando aparece una expresión constante en un contexto de asignación, el compilador de Java calcula el valor de la expresión y ve si está en el rango del tipo al que está asignando. Si es así, se aplica una conversión primitiva de restricción implícita .
En el primer ejemplo, 'a' + 'b'
es una expresión constante, y su valor cabrá en a char
, por lo que el compilador permite el estrechamiento implícito del int
resultado de la expresión a a char
.
En el segundo ejemplo, y
es una variable, por y + 'b'
lo que NO es una expresión constante. Entonces, aunque Blind Freddy puede ver que el valor encaja, el compilador NO permite ningún estrechamiento implícito y obtiene un error de compilación que dice que int
no se puede asignar un valor a char
.
Hay algunas otras advertencias sobre cuándo se permite una conversión primitiva de restricción implícita en este contexto; consulte JLS 5.2 y JLS 15.28 para conocer todos los detalles.
Este último explica en detalle los requisitos para una expresión constante . Puede que no sea lo que piensas. (Por ejemplo, simplemente declarar y
como final
no ayuda).
char
, el valor de'a' + 'b'
no sería195
pero'Ã'