@ starblue, existe algum exemplo da vida real em que o tipo de byte Java é aplicável?
Thorbjørn Ravn Andersen
Se houver dados especificados como um byte, use um Java bytepara maior clareza, por exemplo, nos parâmetros. Nesse caso, o fato de você não poder atribuir intvalores poderá até pegar alguns bugs. Ou use bytepara economizar espaço em matrizes. Eu não usaria bytepor um único valor que só se encaixa em um byte.
starblue
Respostas:
172
As constantes são avaliadas como ints, portanto, 2147483647 + 1estouram e fornecem um novo int, que é atribuível a int, enquanto 127 + 1também é avaliado como intigual a 128, e não é atribuído a byte.
O problema é do tipo intdevido à promoção numérica binária, o valor 127é um arenque vermelho.
31711 starblue
Eu preferiria que constantes fossem avaliadas com precisão infinita e também fornecessem um erro em int i = 2147483647 + 1;
Eduardo
@MByD: Como você disse " while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.", isso significa que 50 + 1 será avaliado como bytee, portanto, é atribuível a byte?
Bhushan
1
@ 10101010 - não exatamente. será atribuível ao byte, mas primeiro (de acordo com o padrão) será avaliado como int.
MByD 27/10/11
35
O literal 127 denota um valor do tipo int. O mesmo acontece com o literal 1. A soma desses dois é o número inteiro 128. O problema, no segundo caso, é que você está atribuindo isso a uma variável do tipo byte. Não tem nada a ver com o valor real das expressões. Tem a ver com Java que não suporta coerções (*). Você precisa adicionar um typecast
byte b =(byte)(127+1);
e depois compila.
(*) pelo menos não do tipo String-to-integer, float-to-Time, ... Java suporta coerções se elas são, de certo modo, sem perda (Java chama isso de "ampliação").
E não, a palavra "coerção" não precisava ser corrigida. Foi escolhido de maneira muito deliberada e correta. Da fonte mais próxima em mão (Wikipedia): "Na maioria dos idiomas, a palavra coerção é usada para denotar uma conversão implícita , durante a compilação ou durante o tempo de execução". e "Na ciência da computação, conversão de tipos, conversão de tipos e coerção são formas diferentes de, implícita ou explicitamente, alterar uma entidade de um tipo de dados para outro".
Seu exemplo de código provavelmente deve ser byte b = (byte) 127 + 1; que é 'Adicionar 1 a um valor máximo de bytes', seu exemplo apenas transforma o valor int de 128 em um valor de byte.
NKCSS
6
@NKCSS - Eu não acho que você esteja certo - converta (byte)(127 + 1)128 (número inteiro) em um byte, enquanto isso (byte)127 + 1converte 127 em um byte, mas novamente em um int, já que é adicionado a 1 (int) e você obtenha 128 (int) e o erro permanece.
MByD 31/07
6
Como evidência para @MByD:
O seguinte código compila:
byte c =(byte)(127+1);
Porque, embora a expressão (127 + 1)seja int e esteja fora do escopo, byteo resultado é convertido byte. Essa expressão produz -128.
Além disso, se a expressão for uma expressão constante (§15.28) do tipo byte, short, char ou int:
Uma conversão primitiva de restrição pode ser usada se o tipo da variável for byte, short ou char, e o valor da expressão constante for representável no tipo da variável.
Sem essa cláusula, não poderíamos escrever
byte x =0;char c =0;
Mas devemos ser capazes de fazer isso? Acho que não. Há muita mágica acontecendo na conversão entre os primitivos, é preciso ter muito cuidado. Eu me esforçava para escrever
quanto à pergunta que deveríamos ser capazes de ... eu não vejo realmente nada de errado com isso, byte x = 0mas, novamente, eu sou um programador em C.
Grady Player
Talvez eu pudesse ver um argumento contra char c = 0, mas por que o byte x = 0 está errado?
Michael Burge
É enganoso para olhos não treinados, pensando que eles estão atribuindo um byte 0 a uma variável de byte. Não há muitos danos neste exemplo, mas, em geral, operar em byte / short / char pode ficar muito confuso devido a conversões implícitas. Eles são muito mais complicados do que as pessoas pensariam. Quero o máximo de clareza possível no meu código, não introduza nenhuma incerteza com o objetivo de salvar alguns pressionamentos de tecla.
#
Uma regra semelhante se aplica quando a conversão primitiva de restrição é longa para int, por exemplo, int i = 1 + 0L? Basta perguntar, porque o texto citado explicitamente deixa esse caso de fora.
byte
tipo de dados é tão doloroso ?!byte
assinado em vez de não assinado.byte
para maior clareza, por exemplo, nos parâmetros. Nesse caso, o fato de você não poder atribuirint
valores poderá até pegar alguns bugs. Ou usebyte
para economizar espaço em matrizes. Eu não usariabyte
por um único valor que só se encaixa em um byte.Respostas:
As constantes são avaliadas como ints, portanto,
2147483647 + 1
estouram e fornecem um novo int, que é atribuível aint
, enquanto127 + 1
também é avaliado comoint
igual a128
, e não é atribuído abyte
.fonte
int
devido à promoção numérica binária, o valor127
é um arenque vermelho.while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.
", isso significa que 50 + 1 será avaliado comobyte
e, portanto, é atribuível abyte
?O literal 127 denota um valor do tipo int. O mesmo acontece com o literal 1. A soma desses dois é o número inteiro 128. O problema, no segundo caso, é que você está atribuindo isso a uma variável do tipo byte. Não tem nada a ver com o valor real das expressões. Tem a ver com Java que não suporta coerções (*). Você precisa adicionar um typecast
e depois compila.
(*) pelo menos não do tipo String-to-integer, float-to-Time, ... Java suporta coerções se elas são, de certo modo, sem perda (Java chama isso de "ampliação").
E não, a palavra "coerção" não precisava ser corrigida. Foi escolhido de maneira muito deliberada e correta. Da fonte mais próxima em mão (Wikipedia): "Na maioria dos idiomas, a palavra coerção é usada para denotar uma conversão implícita , durante a compilação ou durante o tempo de execução". e "Na ciência da computação, conversão de tipos, conversão de tipos e coerção são formas diferentes de, implícita ou explicitamente, alterar uma entidade de um tipo de dados para outro".
fonte
(byte)(127 + 1)
128 (número inteiro) em um byte, enquanto isso(byte)127 + 1
converte 127 em um byte, mas novamente em um int, já que é adicionado a 1 (int) e você obtenha 128 (int) e o erro permanece.Como evidência para @MByD:
O seguinte código compila:
Porque, embora a expressão
(127 + 1)
seja int e esteja fora do escopo,byte
o resultado é convertidobyte
. Essa expressão produz-128
.fonte
Conversão de atribuição JLS3 # 5.2
(variável = expressão)
Além disso, se a expressão for uma expressão constante (§15.28) do tipo byte, short, char ou int:
Uma conversão primitiva de restrição pode ser usada se o tipo da variável for byte, short ou char, e o valor da expressão constante for representável no tipo da variável.
Sem essa cláusula, não poderíamos escrever
Mas devemos ser capazes de fazer isso? Acho que não. Há muita mágica acontecendo na conversão entre os primitivos, é preciso ter muito cuidado. Eu me esforçava para escrever
fonte
byte x = 0
mas, novamente, eu sou um programador em C.int i=0L
é ilegal.