java.lang.Object o = 1; // pourquoi cette compilation?
-
23-09-2019 - |
Question
Je faisais un de ces tests en ligne Java et on m'a demandé cette question:
Q: Indiquez l'affectation correcte:
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);
S'il vous plaît essayer vous-même avant d'aller plus loin.
Eh bien, je peux vous dire que je me suis trompé, je l'ai étudié et trouvé:
//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
Quelqu'un peut-il dire pourquoi:
Object o = 1;
et Object o = "1";
compiler et 1 sortie dans les deux cas, cela me laisse perplexe.
Merci
La solution
"1"
est une instance de la classe String et la chaîne est une sous-classe de la classe d'objets en Java (comme toute autre classe). 1
est encadré en un entier, qui est également dérivé de l'objet.
Autres conseils
Parce que "1"
est une instance d'un String
, et depuis 1,5 1
est auto-boxable à un Integer
; les deux types sont des sous-types de Object
. Avant autoboxing a été introduite, Object o = 1;
ne compilerait pas.
Pour tirer le meilleur parti de cette expérience d'apprentissage, vous devez être au courant de la méthode de Object
de getClass()
. En ajoutant System.out.println(o.getClass().getName())
, vous pouvez également imprimer le nom de la classe que l'objet désigné par o
appartient. Dans votre cas, ils sont java.lang.String
(pour (Object) "1"
) et java.lang.Integer
(pour (Object) 1
).
Juste pour la fin, je dois mentionner que vous pouvez maintenant faire Object o = false;
.
Eh bien, le premier cas « 1 » est un String
littérale, donc une sous-classe d'objet, d'où assignable à lui. En tant que chaîne, elle sortie 1 est relativement simple.
Dans le second cas, l'auto-boxe est en cours. Integer
est une sous-classe d'objet, d'où assignable à lui. De même, la sortie 1 est donc logique parfaite.
En effet, o
est de type Object
. Chaque objet, en Java, étend la Object
de classe. Alors ... quand vous dites Object o = 1
, il convertit 1 à partir int
à Integer
, qui est un Object
. De même, « 1 » est un String
qui est un Object
. Dans les deux cas, l'appel System.out.println
sur une Object
appelle la méthode Object
s de toString
. Dans les deux cas, il imprimera 1.
Vous pouvez mettre Object o = anything;
où anything
est un objet parce que toutes les classes dérivent de la classe Object
. Il fonctionne avec des primitives en raison de fonctionnalité autoboxing qui sont entrées en Java 1.5.