Galera,
Porque é permitido:Short s = (byte)1; E não é permitido:Long l = (int)1; // ou simplismente Long l = 1
Galera,
Porque é permitido:Short s = (byte)1; E não é permitido:Long l = (int)1; // ou simplismente Long l = 1
Galera,Porque é permitido:
Short s = (byte)1;E não é permitido:Long l = (int)1; // ou simplismente Long l = 1
No primeiro caso, você está passando um inteiro para bytes. Isso é possível, pois não há perda de dados.
00000001 é “1” em binário. Em inteiro, é só completar até 32 bits com 0s.
No segundo caso, há um problema de sintaxe, com ou sem a coerção.
Em Java, tipos do tipo long literais terminam com L/l. Sem isso, todo inteiro é interpretado automaticamente como inteiro.
Assim, o certo seria:
Long l = 1L;
ECO2004, agradeço a sua resposta.
Mas neste caso, existe um detalhe importante:Long l = (int)1; // não é permitido
long l2 = (int)1; // é permitido
Com base nisso, mesmo sem o 1L, foi possível a conversão para um long (já que int cabe em long).
O que está me intrigando é o seguinte:
short s2 = (byte)1; // (Compila) primitivo menor pode ser atribuido a um tipo primitivo maior
Short s = (byte)1; // (Compila) primitivo menor pode ser atribuido a um wrapper maior
O que está me intrigando é o seguinte:
long l = (int)1; // (Compila) primitivo menor pode ser atribuido a um tipo primitivo maior, mesmo sem o L para identificar um literal long
Long l2 = (int)1; // (NÃO Compila) primitivo menor NÃO pode ser atribuido a um wrapper maior
Quero entender porque a regra básica não funciona igualmente para os 2 casos.
Peço que avaliem a pergunta com atenção, pois parece uma pergunta simples de cast e boxing, mas creio que não seja.
Leia aqui, está tudo explicado, além do autor da resposta indicar o trecho da especificação da linguagem Java que trata do assunto.
ECO2004, agradeço a sua resposta.Mas neste caso, existe um detalhe importante:
Long l = (int)1; // não é permitido long l2 = (int)1; // é permitido
Com base nisso, mesmo sem o 1L, foi possível a conversão para um long (já que int cabe em long).O que está me intrigando é o seguinte:
- byte cabe em short
- é permitido um primitivo byte ser atribuido a um wrapper Short (não entendo como, pois segundo a regra, não é possível ampliar ou reduzir e depois fazer o boxing)
e então temos:
short s2 = (byte)1; // (Compila) primitivo menor pode ser atribuido a um tipo primitivo maior Short s = (byte)1; // (Compila) primitivo menor pode ser atribuido a um wrapper maiorO que está me intrigando é o seguinte:
- int cabe em long
- não é permitido um primitivo int ser atribuido a um wrapper Long (concordo, pois segundo a regra, não é possível ampliar ou reduzir e depois fazer o boxing)
e então temos:
long l = (int)1; // (Compila) primitivo menor pode ser atribuido a um tipo primitivo maior, mesmo sem o L para identificar um literal long Long l2 = (int)1; // (NÃO Compila) primitivo menor NÃO pode ser atribuido a um wrapper maiorQuero entender porque a regra básica não funciona igualmente para os 2 casos.
Peço que avaliam a pergunta com atenção, pois parece uma pergunta simples de cast e boxing, mas creio que não seja.
Que nem eu disse, ocorre (ocorria) erro de sintaxe se eu não colocar um L ou l depois de um literal antes de atribui-lo à variável de tipo long.
No caso:
long l = (int)1;
Normalmente não compilaria. Aprendi que todos os valores literais inteiros eram interpretados como int. Assim, se eu quisesse um literal como long, teria que colocar L depois do valor. Será que é coisa do Java 7?
[b]A transformação de um valor de tipo menor em outro de tipo maior é chamado de upcast, usado em operações ou passagens de parâmetro. Não sabia que tinha isso com atribuições de valores a variáveis. Testei várias vezes em programas anteriores e sempre dava erro.
Por exemplo:
4/2.0 seria o mesmo que 4.0/2.0, pois ocorre um upcast.
Da mesma forma, se tenho um método void metodo(long x) e o invoco como metodo(2) ao invés de metodo(2L), ocorre também um upcast.
[/b]
No segundo caso:
Long l2 = (int)1
Volto a minha explicação anterior: colocando um L depois do literal, o valor é interpretado como um long. Envolvê-lo em um Long é trivial. Envolver um inteiro com um Long é um erro de sintaxe.
Obrigado pelo retorno de todos!
Deixou aqui um resumo do resumo (de acordo com o que entendi sobre o link enviado) do motivo pelo qual a situação acima acontece:
Para deixar claro:
ampliação implícita = ex:atribuir um short para um int. int i = (short)10;
redução implícita = ex: atribuir um int para um short, mas apenas se for através de um literal explicito que seja suportado, ex: short s = 10, pois o 10 é um literal explicito que cabe em um short)
De modo geral, NÃO é permitido fazer (ampliação ou redução ) + autoboxing na mesma operação.
Exemplo: Long varLong = 10; // Não compila Neste caso, o java tem que fazer a ampliação do 10 int para 10 long, e depois fazer o boxing para a classe wrapper.
Porém é permitido long varLong = 10; // Compila Neste caso somente é feito a ampliação do 10 int para 10 long;
Porém, existe uma exceção que diz que quando os valores forem do tipo Byte, Short e Integer, é permitido realizar as 2 operações de uma vez (ampliação ou redução + boxing), como no exemplo: Short s = (byte)10; // CompilaNeste caso, o java faz a ampliação do 10 byte para 10 short, e ainda faz o boxing para a classe wrapper (10 short para new Short(10)).
Gostaria que alguém mais experiente validasse essa minha afirmação, pois como essa área de Boxing, Atribuição e Wrapper é muito complexa, pode ser que exista mais detalhes ou que eu tenha entendido algo errado.