Olá Vinicius!
O código compila por causa do auto-boxing (inserir na caixa) e auto-unboxing (remover da caixa) presentes no Java. O que é isso?
Quando você tem um int
e quer usar um Integer
, basta fazer uma atribuição, e você tem um auto-boxing.
int a = 42;
Integer b = a;
A JVM se incumbe de automaticamente transformar, em tempo de execução, o tipo primitivo no objeto, ou seja, ele é empacotado. O mesmo vale para o caso contrário, o auto-unboxing
Integer a = new Integer(42);
int b = a;
Neste caso o tipo valor é retirado do objeto e tornado primitivo, ou seja, desempacotado.
O mesmo vale para a linha A, pois o número 12 sofre auto-boxing para um objeto do tipo Integer
, que por padrão extende Object
e portanto tem o método toString()
permitindo que seja inserido na formatação %s
.
Já sobre fazer casting de double
pra byte
funciona, porém as casas decimais são perdidas e o valor é limitado ao intervalo [-128,128[
. Como originalmente tínhamos um número inteiro dentro deste escopo, a saída final não muda.
System.out.printf("%s", (byte)10.5); // 10
System.out.printf("%s", (byte)11.0); // 11
System.out.printf("%s", (byte)(double)11); // 11
Porém esse casting precisa ser explícito. O código a seguir não compila
double d = 42.0;
byte b = d;
Mas este sim:
double d = 42.0;
byte b = (byte)d;
Faça um experimento pra entender:
for (double d = -130; d < 130; d += 0.5) {
System.out.printf("%s\n", (byte) d);
}
Espero que tenha dado pra entender! =)
Bom trabalho e bons estudos!