java.lang.Object o = 1; // Por que isso compila?
-
23-09-2019 - |
Pergunta
Eu estava fazendo um desses testes de Java on -line e fui feito esta pergunta:
P: Indique atribuição correta:
Long l = 1;
Double d = 1;
Integer i = 1;
String s = 1;
Object o = "1";
System.out.println(o);
o = 1;
System.out.println(o);
Por favor, tente você mesmo antes de ir mais longe.
Bem, eu posso dizer que entendi errado, eu o investigei e encontrei:
//Long l = 1; //cannot widen and then box
Long ll = 1L;//no need to widen, just box
//Double d = 1;//cannot widen and then box
Double dd = 1d;//no need to widen, just box
Integer i = 1;//no need to widen, just box
//String s = 1;//cannot do implicit casting here
Object o = "1";//this compiles and is just plain weird
System.out.println(o);//output is 1
o = 1;//this also compiles and is also weird
System.out.println(o);//output is 1
Alguém pode dizer o porquê:
Object o = 1;
e Object o = "1";
Compilar e produzir 1 em ambos os casos, isso está me intrigando.
Muito Obrigado
Solução
"1"
é uma instância da classe String e a String é uma subclasse da classe de objeto em Java (como qualquer outra classe). 1
é encaixotado em um número inteiro, que também é derivado do objeto.
Outras dicas
Porque "1"
é uma instância de um String
, e desde 1.5 1
é automático de caixa para um Integer
; Ambos os tipos são subtipos de Object
. Antes da introdução da auto -box, Object o = 1;
não compilaria.
Para aproveitar ao máximo essa experiência de aprendizado, você deve estar ciente Object
's getClass()
método. Adicionando System.out.println(o.getClass().getName())
, você também pode imprimir o nome da classe que o objeto referido por o
pertence a. No seu caso, eles são java.lang.String
(por (Object) "1"
) e java.lang.Integer
(por (Object) 1
).
Apenas para conclusão, devo mencionar que agora você pode fazer Object o = false;
.
Bem, o primeiro caso "1" é um String
literal, portanto, uma subclasse de objeto, portanto atribuível a ele. Como uma string, a saída de 1 é relativamente simples.
No segundo caso, está ocorrendo boxing automático. Integer
é uma subclasse de objeto, portanto atribuível a ele. Da mesma forma, a saída de 1 faz todo o sentido.
Isto é porque o
é do tipo Object
. Todo objeto, em Java, estende a aula Object
. Então ... quando você diz Object o = 1
, ele converte 1 para de int
para Integer
, que é um Object
. Da mesma forma, "1" é um String
que é um Object
. Nos dois casos, ligando System.out.println
em um Object
invoca o Object
s toString
método. Nos dois casos, ele imprimirá 1.
Você pode colocar Object o = anything;
Onde anything
é qualquer objeto porque todas as classes derivam do Object
classe. Funciona com as primitivas devido ao recurso de autoboxing que veio no Java 1.5.