Java:por que recebo a mensagem de erro “Tipo incompatível:não é possível converter int em byte”

StackOverflow https://stackoverflow.com/questions/81392

Pergunta

Se você declarar variáveis ​​do tipo byte ou short e tentar realizar operações aritméticas sobre elas, receberá o erro "Tipo incompatível:não é possível converter int em short" (ou correspondentemente "Incompatibilidade de tipo:não é possível converter int em byte").

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

Neste exemplo, o erro de compilação está na terceira linha.

Foi útil?

Solução

Embora os operadores aritméticos são definidos para operar em qualquer tipo numérico, de acordo com a especificação da linguagem Java (5.6.2 Binário Promoção Numérico), operandos do tipo byte e curtas são automaticamente promovidos para int antes de ser entregue aos operadores.

Para executar operações aritméticas em variáveis ??do tipo byte ou curto, você deve colocar a expressão entre parênteses (dentro dos quais as operações serão realizadas como tipo int), e depois expressos nas costas resultado para o tipo desejado.

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

Aqui está um follow-on pergunta aos gurus Java reais: por quê? O byte tipos e curta são perfeitamente bem tipos numéricos. Por que Java não permite operações aritméticas diretos sobre esses tipos? (A resposta não é "perda de precisão", como não há nenhuma razão aparente para converter para int em primeiro lugar.)

Update: jrudolph sugere que este comportamento é baseado nas operações disponíveis na JVM, especificamente, que apenas os operadores integral e duas palavras são implementadas. Assim, para operador em bytes e shorts, eles devem ser convertidos para int.

Outras dicas

A resposta à sua pergunta de follow-up é aqui:

operandos do tipo byte e short são automaticamente promovidos para int antes de ser entregue aos operadores

Assim, no seu exemplo, a e b são ambos convertidos para um int antes de ser entregue ao operador +. O resultado da adição de dois ints juntos é também um int. Tentando, em seguida, atribuir esse int para um valor byte causa o erro porque há uma perda potencial de precisão. Ao lançar explicitamente o resultado que você está dizendo o compilador "Eu sei o que estou fazendo".

Eu acho que, a questão é, que os suportes JVM apenas dois tipos de valores da pilha: palavra size e palavra dupla de tamanho.

Em seguida, eles provavelmente decidiram que seria necessário apenas uma operação que funciona em palavra dimensionado inteiros na pilha. Então só há iadd, IMUL e assim por diante a nível bytecode (e há operadores para bytes e shorts).

Para que você obtenha um valor de int como resultado dessas operações que Java não pode converter com segurança de volta para o byte menor e tipos de dados curtos. Então eles forçá-lo a elenco para reduzir o valor de volta para byte / short.

Mas no final você está certo: Este comportamento não é consistente com o comportamento de inteiros, por exemplo. Você pode sem problema adicionar dois inteiros e obter nenhum erro se o resultado transborda.

A linguagem Java sempre promove argumentos dos operadores aritméticos para int, long, float ou double. Portanto, tome a expressão:

a + b

em que a e b são de tipo byte. Este é um atalho para:

(int)a + (int)b

Esta expressão é do tipo int. É claramente faz sentido dar um erro ao atribuir um valor int para uma variável byte.

Por que a língua ser definida desta forma? Suponhamos que uma era de 60 e de b foi de 70, então a + b é -126 - número inteiro de transbordamento. Como parte de uma expressão mais complicada que era esperado para resultar em um int, isso pode se tornar um problema difícil. Restringir o uso de byte e curta a matriz de armazenamento, constantes para formatos de arquivo / protocolos de rede e puzzlers.

Há uma gravação interessante do JavaPolis 2007. James Gosling está dando um exemplo sobre como complicado aritmética sem sinal é (e por que não é em Java). Josh Bloch assinala que o seu exemplo dá o exemplo errado sob aritmética assinado normal também. Para aritmética compreensível, precisamos de precisão arbitrária.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top