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 += ycon los tipos más pequeños, el compilador usará iaddy 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()
Aunque ces 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.
chares 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".
Me sorprende que no haya recibido una advertencia del compilador en el segundo caso sobre una posible pérdida de precisión debido al estrechamiento.
Hot Licks
@eboix: usted escribió "el compilador pone automáticamente a carbón o int" [sic] ... Lo cual no es correcto porque un int no está "fundido" a un int y viniendo de un int a un carbón no se llama una "conversión" pero una "conversión primitiva de reducción"; )
TacticalCoder
Si. Yo también esperaba eso. De hecho, había escrito parte de mi respuesta sobre eso antes de crear mi programa, pero luego lo eliminé una vez que vi que no recibía advertencias ni errores.
eboix
@eboix: eh eh :) Lo habría editado pero todavía no tengo 2000 puntos de reputación, de ahí mi comentario en lugar de una edición; )
TacticalCoder
Si quieres, @ user988052, puedo volver a cambiarlo a lo que era y puedes editarlo, obteniendo puntos. Aún puede editarlo si tiene menos de 2000 puntos de reputación. Lo único es que la persona que hizo la publicación tiene que aceptar la edición. Lo volveré a cambiar ahora mismo para que puedas obtener los dos puntos que te pertenecen por derecho.
eboix
1
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.
El uso charcomo valor numérico está completamente dentro de su propósito, por lo que JLS dedica tanta verborrea a dicho uso.
Lew Bloch
1
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 intal agregar dos chars.
publicclassCharAdditionTest{
publicstaticvoidmain(String args[]){
char a = 'a';
char b = 'b';
Object obj = a + b;
System.out.println(obj.getClass().getName());
}
}
Esta no es una verificación convincente, porque ha incluido una conversión de boxeo en la mezcla. Los tipos inty Integerno son lo mismo. Una verificación más convincente es intentar asignar a + ba una intvariable o una charvariable. Este último da un error de compilación que dice en efecto "no se puede asignar una inta una char".
Stephen C
0
charse representa como Unicodevalores y donde los valores Unicode se representan \useguido de Hexadecimalvalores.
Como cualquier operación aritmética sobre charvalores promovidos int, el resultado de 'a' + 'b'se calcula como
1.) Aplicar los Unicodevalores en el charuso correspondienteUnicode Table
2.) Aplicar la conversión de hexadecimal a decimal y luego realizar la operación en Decimalvalores.
Para su información, mi respuesta detallada al comentario anterior ha sido eliminada por modificaciones que explicaban el motivo de la migración de mi respuesta de una publicación eliminada. Si mi respuesta ha sido eliminada para encubrir las fallas de la moderación SO, ¿puede al menos eliminar el comentario anterior o indicar la audiencia de alguna manera para que no tenga que escribir otro comentario? preguntas a los mods SO
Pavneet_Singh
Mantengo mi comentario. Como le respondí ... pero luego eliminé ... la razón por la que publicó esta Pregunta aquí no cambia el hecho de que está un 95% fuera del tema de la pregunta y un 5% de repetición de las respuestas anteriores. Si desea guardar los resultados de su esfuerzo desperdiciado, sería más apropiado guardarlo en su disco duro. O busque alguna otra pregunta que sea relevante.
Stephen C
Si tiene alguna queja con los moderadores, consúltela en meta.stackoverflow.com. Y proporcione pruebas. Todo lo que estoy tratando de hacer aquí es ordenar >> estas << Preguntas y Respuestas.
Stephen C
Entiendo su punto de vista, pero no puedo entender el hecho de ignorar los detalles de la conversión Unicode con ejemplos, como un valor adicional que podría ayudar a algunos lectores, así que me gustaría mantener esta respuesta (entiendo que no es útil para usted y parece fuera de lugar) tema). Evito los lugares meta y similares, ya que no es fácil hacer esas cosas sin poder o apoyo, lo que requiere mucho tiempo y esfuerzo. Prefiero mantener mi paz interior Sire.
Pavneet_Singh
0
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'; // OKchar y = 'a';
char z = y + 'b'; // Compilation error
Que esta pasando? Quieren decir lo mismo, ¿no? ¿Y por qué es legal asignar un inta charen 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 intresultado de la expresión a a char.
En el segundo ejemplo, yes 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 intno 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 ycomo finalno ayuda).
char
, el valor de'a' + 'b'
no sería195
pero'Ã'
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 :
Pero tenga en cuenta lo que dice sobre los operadores de asignación compuesta (como + =) :
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 simularx += 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 comoi2c
("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')
fuente
Las operaciones aritméticas binarias en
char
ybyte
(yshort
) promueven aint
- JLS 5.6.2.fuente
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) dec+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 elc
tipo char y producetemp=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 dechar
, 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".fuente
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:
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 ).
fuente
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.
fuente
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 doschar
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
fuente
int
yInteger
no son lo mismo. Una verificación más convincente es intentar asignara + b
a unaint
variable o unachar
variable. Este último da un error de compilación que dice en efecto "no se puede asignar unaint
a unachar
".char
se representa comoUnicode
valores y donde los valores Unicode se representan\u
seguido deHexadecimal
valores.Como cualquier operación aritmética sobre
char
valores promovidosint
, el resultado de'a' + 'b'
se calcula como1.) Aplicar los
Unicode
valores en elchar
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
Unicode To Decimal Converter
Ejemplo
0061
0062
Por lo tanto
97 + 98 = 195
Ejemplo 2
char Unicode Decimal Ջ 054b 1355 À 00c0 192 -------- 1547 + 1163 - 7 / 260160 * 11 %
fuente
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
achar
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 achar
, por lo que el compilador permite el estrechamiento implícito delint
resultado de la expresión a achar
.En el segundo ejemplo,
y
es una variable, pory + '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 queint
no se puede asignar un valor achar
.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
comofinal
no ayuda).fuente