2008-09-17 18 views
9

Si declara variables de tipo byte o corto e intenta realizar operaciones aritméticas en ellas, recibirá el error "No coinciden los tipos: no se puede convertir int to short "(o correspondientemente" Tipo desajuste: no se puede convertir int a byte ").Java: por qué recibo el mensaje de error "No coinciden los tipos: no se puede convertir en byte"

byte a = 23; 
byte b = 34; 
byte c = a + b;

En este ejemplo, el error de compilación está en la tercera línea.

+1

IIRC La JVM almacena bytes y cortos como ints, por lo que generalmente se obtienen muy pocos beneficios con el uso de estos dos tipos de datos. Por supuesto, me doy cuenta de que estás haciendo algo mucho más complejo que tu ejemplo y probablemente tengas una muy buena razón. –

Respuesta

8

Aunque los operadores aritméticos se definen para operar en cualquier tipo numérico, de acuerdo con la especificación de lenguaje Java (5.6.2 Promoción binaria numérica), los operandos de tipo byte y corto se promueven automáticamente a int antes de entregarse a los operadores.

Para realizar operaciones aritméticas en variables de tipo byte o corto, debe encerrar la expresión entre paréntesis (dentro de las cuales las operaciones se llevarán a cabo como tipo int) y luego devolver el resultado al tipo deseado.

byte a = 23; 
byte b = 34; 
byte c = (byte) (a + b);

Aquí hay una pregunta de seguimiento para los gurús reales de Java: ¿por qué? Los tipos byte y short son tipos numéricos perfectamente precisos. ¿Por qué Java no permite operaciones aritméticas directas en estos tipos? (La respuesta no es "pérdida de precisión", ya que no hay ninguna razón aparente para convertir a int en primer lugar.)

Actualización: jrudolph sugiere que este comportamiento se basa en las operaciones disponibles en la JVM, específicamente, que solo se implementan operadores de palabra completa y de doble palabra. Por lo tanto, para el operador en bytes y cortos, se deben convertir a int.

+0

Supongo que se debe al rendimiento. En algunas CPU, puede ser más costoso usar operandos más pequeños que los registros de la CPU. Probablemente incluso utilizó un byte de 32 bits para almacenar byte y short, para mantenerlos alineados en la memoria. – jassuncao

+0

ya que encontré que - las operaciones se llevan a cabo en los registros de la CPU, pero sí están alineados a 32 bits. y tampoco puedes ejecutar el operador + en caracteres – bestsss

5

La respuesta a su pregunta de seguimiento está aquí:

operandos de tipo byte y short automáticamente se transfieren a int antes de ser entregado a los operadores

Así, en su ejemplo, a y b se convierten ambos a int antes de ser entregados al operador +. El resultado de agregar dos int s juntos también es un int. Al intentar asignar ese int a un valor de byte, se produce el error debido a una posible pérdida de precisión. Al emitir explícitamente el resultado, le está diciendo al compilador "Sé lo que estoy haciendo".

2

Creo que la cuestión es que la JVM admite solo dos tipos de valores de pila: tamaño de palabra y tamaño de palabra doble.

Luego, probablemente decidieron que necesitarían solo una operación que funcione en enteros de tamaño de palabra en la pila. Por lo tanto, solo hay iadd, imul, etc. en el nivel de código de bytes (y no hay operadores para bytes y cortos).

Así obtiene un valor int como resultado de estas operaciones que Java no puede convertir de forma segura a los tipos de datos de byte y de datos cortos más pequeños. Entonces te obligan a lanzar para reducir el valor de nuevo a byte/corto.

Pero al final tiene razón: este comportamiento no es coherente con el comportamiento de ints, por ejemplo. Puede sin problemas agregar dos entradas y no obtener ningún error si el resultado se desborda.

1

El lenguaje Java siempre promueve los argumentos de operadores aritméticos a int, long, float o double.Así que tome la expresión:

a + b 

donde a y b son de tipo byte. Esto es una abreviatura de:

(int)a + (int)b 

Esta expresión es del tipo int. Claramente tiene sentido dar un error al asignar un valor int a una variable de byte.

¿Por qué el lenguaje se define de esta manera? Supongamos que a era 60 yb era 70, entonces a + b es -126 - desbordamiento entero. Como parte de una expresión más complicada que se espera que dé como resultado un int, esto puede convertirse en un error difícil. Restrinja el uso de byte y corto a almacenamiento en matriz, constantes para formatos de archivo/protocolos de red y rompecabezas.

Hay una grabación interesante de JavaPolis 2007. James Gosling está dando un ejemplo sobre lo complicada que es la aritmética sin signo (y por qué no está en Java). Josh Bloch señala que su ejemplo da el ejemplo incorrecto bajo la aritmética normal firmada también. Para una aritmética comprensible, necesitamos precisión arbitraria.

Cuestiones relacionadas