Autoboxing

Por favor,

Tenho a seguinte dúvida:

	Integer     i = 10; 	//blz...Realizou um Autoboxing para wrapper Integer...Integer i = new Integer(10);
	
	Long 	l = 10L;	// Compila 

	Long 	l = 10;	            // Por que não compila? se um int pode ser ampliado para um long
			                    // Sei que Autoboxing não pode ampliar e depois realizar um boxing...

	Short 	s = 10;	            // Mais e neste caso...Se um int não pode realizar um Autoboxing direto para um Long
			                    // por que pode para a classe wrapper Short?

Então, o literal 10 é um int…certo? A pergunta é porque posso ir direto para classe wrapper Short mais não para classe wrapper Long ou Double?.. para Long tenho que indicar que o literal é um long com sufixo “L”… Olha, procure descobri…mais não consegui achar uma resposta simples para isso…

Obrigado…

Entschuldigung, mas também não sei a regra certa. Veja o que consegui:

class TesteAutoboxing {
     Byte    b0 = (char) 10;
     Byte    b1 = 10;
     Byte    b2 = 10L; // não
     Byte    b3 = (short) 10;

     Character c0 = (char) 10;
     Character c1 = 10;
     Character c2 = 10L; // não
     Character c3 = (short) 10;

     Short   s0 = (char) 10;
     Short   s1 = 10;
     Short   s2 = 10L; // não
     Short   s3 = (short) 10;

     Integer i0 = (char) 10; // não
     Integer i1 = 10;
     Integer i2 = 10L; // não
     Integer i3 = (short) 10; // não

     Long    l0 = (char) 10; // não
     Long    l1 = 10; // não
     Long    l2 = 10L;
     Long    l3 = (short) 10; // não
}

As linhas indicadas com “// não” são as que dão erros de compilação.

Isso não deve cair na certificação (não caiu na minha prova, por exemplo).

[quote=thingol]Entschuldigung, mas também não sei a regra certa. Veja o que consegui:

class TesteAutoboxing {
     Byte    b0 = (char) 10;
     Byte    b1 = 10;
     Byte    b2 = 10L; // não
     Byte    b3 = (short) 10;

     Character c0 = (char) 10;
     Character c1 = 10;
     Character c2 = 10L; // não
     Character c3 = (short) 10;

     Short   s0 = (char) 10;
     Short   s1 = 10;
     Short   s2 = 10L; // não
     Short   s3 = (short) 10;

     Integer i0 = (char) 10; // não
     Integer i1 = 10;
     Integer i2 = 10L; // não
     Integer i3 = (short) 10; // não

     Long    l0 = (char) 10; // não
     Long    l1 = 10; // não
     Long    l2 = 10L;
     Long    l3 = (short) 10; // não
}

As linhas indicadas com “// não” são as que dão erros de compilação.

Isso não deve cair na certificação (não caiu na minha prova, por exemplo).
[/quote]

Obrigado, tinha encanado com isso…vou seguir adiante…
Valeu

Segundo o Livro da Katty Sierra, SCJP, diz que você tem que fazer o casting ou colocar a letra f(tanto faz, maiúscula ou minúscula) porque o compilador encara todo literal de um float como um double, portanto 64 bits(double) não cabem em 32 bits(float).

Então,

Long    l = 10;

Não é um literal de double e sim de int, porque não tem (.)
Mas mesmo se fosse um double tentando ser atribuido em um long, porque o seguinte funciona?

Short   s = 10;         // Mais e neste caso...Se um int não pode realizar um Autoboxing direto para um Long  
                                          // por que pode para a classe wrapper Short?  

Para o caso de atribuição para um wrapper short, a resposta é que em tempo de compilação, é verificado se o litera int está dentro do range de um short que é -32768 to 32767

Compila:

Short s =  32767;

Não compila:

Short s =  32768;

Mas quando atribuo um int em um long, primitivo, não tem problema porque o range de int está dentro do range de long.

long l = 10;

Mais isso não vale quando atribuo um literal int em uma wrapper Long…Sou obrigado a colocar o sufixo no literal “l” ou “L”

Long l = 10; // Não compila

Essa é a dúvida…qual seria a regra para isso?

Bom, são só detalhes da vida…vou continuando…acho que isso não influencia para a prova mesmo…

valeu

lembre-se de um detalhe importante int nao é Integer tipos primitivos é algo completamente diferente das classes Wrappers, um Integer é uma classe e um int nao eh uma classe… quando pensar em classes wrappers foque nela… e nem lembre dos primitivos, porem nao esqueça que é possivel fazer um pequeno relacionamento com tipo primitivos que é o autoboxing, mas vc nao pode dizer que int É-UM Integer.

em caso de duvida eh bom ler novamente esse capitulo da kathy e com calma prestando atencao entre linhas no exame a pegadinhas com isso e nao sao poucas… as vezes a questao la era de threads, e tinha algo no meio que nao compilava por quebrar essas regras Wrappers.

[quote=LPJava]lembre-se de um detalhe importante int nao é Integer tipos primitivos é algo completamente diferente das classes Wrappers, um Integer é uma classe e um int nao eh uma classe… quando pensar em classes wrappers foque nela… e nem lembre dos primitivos, porem nao esqueça que é possivel fazer um pequeno relacionamento com tipo primitivos que é o autoboxing, mas vc nao pode dizer que int É-UM Integer.

em caso de duvida eh bom ler novamente esse capitulo da kathy e com calma prestando atencao entre linhas no exame a pegadinhas com isso e nao sao poucas… as vezes a questao la era de threads, e tinha algo no meio que nao compilava por quebrar essas regras Wrappers.[/quote]

Tudo bem, sei a diferença entre classe wrapper e os primitivos, mais a dúvida não é essa. É a seguinte:

Ao meu ver isto acontece pois está tentando converter um int em um Long (repare que um é tipo primitivo e outro objeto). Creio que você esperava que ele primeiro tornasse o int em um long e depois em Long (o que daria certo), mas ele tenta direto do int para Long, o que ele não faz. Mas posso estar enganado :smiley:

Ainda não consegui achar a regra.

Eu sei que se fosse sem autoboxing (ou seja, algo como

char x = 0xFFFF; // isto compila
char y = 0x10000; // isto dá erro de compilação

), o Java pega a constante inteira (se você não puser um tipo nela) e, se ela for pequena suficiente para caber na variável (por exemplo, entre -128 e +127 para byte, entre 0 e 65535 para char, entre -32768 e +32767 para short), você não precisa especificar se é byte, char, short ou int. Mesmo usando um casting (exceto no caso em que você põe um L no final do número), ele ainda pega essa regra de checar o valor para ver se é necessário usar um casting ou não.

Mas no caso de autoboxing ele não segue exatamente essa regra; eu em particular prefiro nunca confiar em regras mal-definidas (para ter uma idéia, não consegui achar a tal regra na Java Language Specification) e acho que isso deve depender da versão do compilador (por exemplo, não sei se o mesmo código compila com os mesmos warnings no Eclipse e no compilador do JDK).

simples! vc nao pode dizer que um int é um Long mas vc pode dizer que um int É-UM long. Até pq nao tem logica vc dizer que um int é um Long. ja que sao tipos diferentes.

a questao eh essa pq nao compila!

creio que seja o seguinte.

um primitivo int cabe em um long;

long l = 10;

já quando tenta fazer a atribuição de um int a um wrapper Long, não é possivel pelo fato de nao ser possivel atribuir um wrapper Integer (após o boxing) a outro wrapper. Pois estao no mesmo nivel da arvore de heranca.

Com isso voce precisa especificar que é um long que voce está atribuindo.

Long l = 10L;

a unica explicacao que achei…agora porque o no Short da certo nao sei.

abraco

[code] public class teste {
public static void main(String[] x){

long 	l1 	= 10L;	
Long 	l2 	= new Long(10);
Long	l3	= l2;

}
}[/code]

Cara, lembrando que os Wrapper são Objetos, o wrapper deve ser iniciados para que os mesmos possam fazer um Conversão do valor inserido no Construtor!

Abraço!

Nao compila pq no caso citado no topico, seria necessario ocorrer uma AMPLIACAO seguida de BOXING.
Certeza absoluta nao tenho mas me lembro de uma regra assim, que NAO podia… nao lembro exatamente se era (ampliar -> boxing) ou (boxing -> ampliar)

até onde eu lembro é: eu não posso ampliar e depois reduzir!

você não pode fazer uma ampliação e depois um boxin.

por exemplo com este mesmo exemplo que estamos discutindo:


 Long l = 10; // Erro, pois faria uma ampliação de int para long e depois um boxing para o wrapper Long   
                    // o que poderia tentar ser feito era uma apliação para o wrapper Integer e depois mandar para Long, mas não é possível pois
                    // estão no mesmo nível de hierarquia da arvore de herança

o que você pode fazer é:

 public void methodA(Object o) {
    Long l = (Long) o;
 }

 long l = 10L;
 methodA(l);

pois estaria fazendo boxing para um Long e depois passando para uma superclasse.

se estiver errado em algo me corrijam.
Abraço a todos

LPJava falou tudo…rss…e nao esquecendo que Wrappers são imutaveis…nao espere no exame que vai achar perguntas sobre wrappers assim …perguntando se compila ou nao …rss…eles vao simplismente jogar elas la …e pergutar sobre outra coisa…rsss…normal…
Resumindo…::esquece de tipos primitivos quando estiver estudando Wrappers…