Je constate un gain de performances lors de l'utilisation getClass()
et de l' ==
opérateur par rapport à l' instanceOf
opérateur.
Object str = new Integer("2000");
long starttime = System.nanoTime();
if(str instanceof String) {
System.out.println("its string");
} else {
if (str instanceof Integer) {
System.out.println("its integer");
}
}
System.out.println((System.nanoTime()-starttime));
starttime = System.nanoTime();
if(str.getClass() == String.class) {
System.out.println("its string in equals");
} else {
if(str.getClass() == Integer.class) {
System.out.println("its integer");
}
}
System.out.println((System.nanoTime()-starttime));
Existe-t-il une directive, laquelle utiliser getClass()
ou instanceOf
?
Étant donné un scénario: je connais les classes exactes à associer, c'est-à- String
dire Integer
(ce sont des classes finales), etc.
L'utilisation d'un instanceOf
opérateur est-elle une mauvaise pratique?
java
class
instanceof
goutte
la source
la source
Réponses:
La raison pour laquelle la performance de
instanceof
etgetClass() == ...
est différente est qu'ils font des choses différentes.instanceof
teste si la référence d'objet sur le côté gauche (LHS) est une instance du type sur le côté droit (RHS) ou un sous-type .getClass() == ...
teste si les types sont identiques.Il est donc recommandé d'ignorer le problème de performances et d'utiliser l'alternative qui vous donne la réponse dont vous avez besoin.
Pas nécessairement. La surutilisation de l'un
instanceOf
ou l' autre ougetClass()
peut être une «odeur de conception». Si vous ne faites pas attention, vous vous retrouvez avec une conception où l'ajout de nouvelles sous-classes entraîne une quantité importante de remaniement du code. Dans la plupart des situations, l'approche préférée consiste à utiliser le polymorphisme.Cependant, il y a des cas où ce ne sont PAS des "odeurs de design". Par exemple, dans
equals(Object)
vous devez tester le type réel de l'argument et renvoyerfalse
s'il ne correspond pas. Le mieux est d'utilisergetClass()
.Des termes comme «meilleure pratique», «mauvaise pratique», «odeur de conception», «anti-modèle», etc. doivent être utilisés avec parcimonie et traités avec suspicion. Ils encouragent la pensée en noir ou blanc. Il vaut mieux porter vos jugements dans leur contexte, plutôt que sur la base d'un pur dogme; par exemple, quelque chose que quelqu'un a dit est "meilleure pratique".
la source
code smell
à utiliser soit. Cela signifie que c'est une conséquence d'un code de mauvaise conception (non polymorphe) qui vous permet d'utiliser l'un ou l'autre. puis-je déduire l'utilisation de l'un ou l'autre de cette façon?instanceof
&getClass()
entre en scène en raison d'une mauvaise conception existante (non polymorphe) du code. Ai-je raison?instanceof
(par exemple) est une mauvaise conception. Il y a des situations où cela peut être la meilleure solution. Pareil pourgetClass()
. Je répète que j'ai dit «abuser» et non «utiliser» . Chaque cas doit être jugé sur ses mérites ... et non en appliquant aveuglément une règle dogmatique mal fondée.Voulez-vous correspondre exactement à une classe , par exemple ne correspond
FileInputStream
qu'à une sous-classe deFileInputStream
? Si tel est le cas, utilisezgetClass()
et==
. Je ferais généralement cela dans unequals
, afin qu'une instance de X ne soit pas considérée comme égale à une instance d'une sous-classe de X - sinon vous pouvez vous retrouver dans des problèmes de symétrie délicats. D'un autre côté, c'est plus généralement utile pour comparer que deux objets appartiennent à la même classe qu'à une classe spécifique.Sinon, utilisez
instanceof
. Notez qu'avecgetClass()
vous devrez vous assurer que vous avez une référence non nulle pour commencer, sinon vous obtiendrez unNullPointerException
, alorsinstanceof
que vous retournerez simplementfalse
si le premier opérande est nul.Personnellement, je dirais que
instanceof
c'est plus idiomatique - mais utiliser l'un ou l'autre de manière intensive est une odeur de design dans la plupart des cas.la source
Je sais que cela fait un moment que cela a été demandé, mais j'ai appris une alternative hier
Nous savons tous que vous pouvez faire:
mais que faire si vous ne savez pas exactement quel type de classe il doit être? vous ne pouvez pas faire de manière générique:
car il donne une erreur de compilation.
Au lieu de cela, voici une alternative - isAssignableFrom ()
Par exemple:
la source
isAssignableFrom
. La bonne façon d'écrire eno instanceof String
utilisant la réflexion estString.getClass().isInstance(o)
. Le javadoc le dit même: Cette méthode est l'équivalent dynamique de l'instanceof
opérateur du langage Java .getClass () a la restriction que les objets ne sont égaux qu'à d'autres objets de la même classe, du même type d'exécution, comme illustré dans la sortie du code ci-dessous:
Les sorties:
SubClass étend ParentClass. subClassInstance est une instance de ParentClass.
Différents getClass () renvoient des résultats avec subClassInstance et parentClassInstance.
la source