Pourquoi ne peut pas une variable « classe » est passé à InstanceOf?
-
25-09-2019 - |
Question
Pourquoi ne compile pas ce code?
public boolean isOf(Class clazz, Object obj){
if(obj instanceof clazz){
return true;
}else{
return false;
}
}
Pourquoi je ne peux pas passer une variable de classe à instanceof
?
La solution
L'opérateur instanceof
fonctionne sur les types de référence, comme Integer
, et non sur les objets, comme new Integer(213)
. Vous voulez probablement quelque chose comme
clazz.isInstance(obj)
Side note: votre code sera plus concis si vous écrivez
public boolean isOf(Class clazz, Object obj){
return clazz.isInstance(obj)
}
Pas vraiment sûr si vous avez besoin d'une méthode plus, cependant.
Autres conseils
instanceof
peut être utilisé uniquement avec les noms de classes explicites (énoncés au moment de la compilation). Pour faire une exécution chèque, vous devez faire:
clazz.isInstance(obj)
a un petit avantage sur clazz.isAssignableFrom(..)
car il traite de l'affaire obj == null
mieux.
Tout d'abord, instanceof
exige que l'opérande à droite est une classe réelle (par exemple obj instanceof Object
ou obj instanceof Integer
) et non une variable de type Class
. Deuxièmement, vous avez fait une erreur de débutant assez commun que vous devriez vraiment pas faire ... le schéma suivant:
if ( conditional_expression ){ return true; } else{ return false; }
Le ci-dessus peuvent être refondus dans:
return conditional_expression;
Vous devez toujours effectuer cette refactoring, car il élimine une redondance instruction if ... else. De même, le return conditional_expression ? true : false;
d'expression est refactorable au même résultat.
Comme d'autres l'ont mentionné, vous ne pouvez pas passer une variable de classe à instanceof
car une des références variables de classe une instance d'un Object , tandis que la main droite de instanceof
doit être type . Cela est, instanceof
ne signifie pas « y est une instance de x Object », cela signifie « y est une instance de type X ». Si vous ne connaissez pas la différence entre un objet et un type, pensez à:
Object o = new Object();
Ici, le type est Object
et o
est une référence à l'instance de l'objet avec ce type. Ainsi:
if(o instanceof Object)
est valide mais
if(o instanceof o)
est pas parce o
sur le côté droit est un objet, pas un type.
Plus spécifique à votre cas, une instance de classe n'est pas un type, il est un Object (qui est créé pour vous par la machine virtuelle Java). Dans votre méthode, Class
est un type, mais clazz
est un objet (bien, une référence à un objet)
Qu'est-ce que vous avez besoin est un moyen de comparer un objet à un objet de classe. Il se trouve que c'est populaire si ce vous est fourni en tant que méthode de l'objet de la classe: isInstance()
.
Voici le Java Doc pour isInstance, ce qui explique ce mieux:
public boolean isInstance(Object obj)
Détermine si l'objet spécifié est compatible avec la cession objet représenté par cette classe. Cette méthode est la dynamique équivalent de l'opérateur instanceof du langage Java. La méthode renvoie true si l'argument de l'objet spécifié est non nul et peut être jeter le type de référence représenté par cet objet de classe sans élever un ClassCastException. Il retourne false autrement.
Plus précisément, si cet objet de classe représente une classe déclarée, cette Procédé renvoie vrai si l'argument de l'objet spécifié est une instance de la classe représentée (ou de l'un de ses sous-classes); il retourne faux autrement. Si cet objet de classe représente une classe de tableau, cette méthode renvoie true si l'argument de l'objet spécifié peut être converti en un objet de la classe de réseau par une conversion d'identité ou d'un élargissement conversion de référence; elle retourne false autrement. Si cet objet de classe représente une interface, cette méthode retourne vrai si la classe ou toute superclasse de l'argument Object spécifié implémente cette interface; elle retourne false autrement. Si cet objet de classe représente un type primitif, cette méthode retourne false.
Paramètres: obj - l'objet de vérifier
retour: true si obj est une instance de cette classe
depuis: JDK1.1