Ich sehe einen Leistungsgewinn bei der Verwendung von getClass()
und ==
Operator über instanceOf
Operator.
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));
Gibt es eine Richtlinie, welche zu verwenden ist getClass()
oder instanceOf
?
In einem vorgegebenen Szenario: Ich weiß genau Klassen angepasst werden, das heißt String
, Integer
(diese sind final Klassen) usw.
Ist die Verwendung des instanceOf
Bedieners eine schlechte Praxis?
java
class
instanceof
Klecks
quelle
quelle
Antworten:
Der Grund, warum die Leistung von
instanceof
undgetClass() == ...
unterschiedlich ist, ist, dass sie unterschiedliche Dinge tun.instanceof
Testet, ob die Objektreferenz auf der linken Seite (LHS) eine Instanz des Typs auf der rechten Seite (RHS) oder ein Subtyp ist .getClass() == ...
prüft, ob die Typen identisch sind.Die Empfehlung lautet daher, das Leistungsproblem zu ignorieren und die Alternative zu verwenden, die Ihnen die Antwort gibt, die Sie benötigen.
Nicht unbedingt. Überbeanspruchung von entweder
instanceOf
odergetClass()
kann "Designgeruch" sein. Wenn Sie nicht vorsichtig sind, erhalten Sie ein Design, bei dem das Hinzufügen neuer Unterklassen zu einer erheblichen Überarbeitung des Codes führt. In den meisten Situationen besteht der bevorzugte Ansatz darin, Polymorphismus zu verwenden.Es gibt jedoch Fälle, in denen dies KEIN "Designgeruch" ist. In müssen Sie beispielsweise
equals(Object)
den tatsächlichen Typ des Arguments testen und zurückgeben,false
wenn es nicht übereinstimmt. Dies geschieht am besten mitgetClass()
.Begriffe wie "Best Practice", "Bad Practice", "Designgeruch", "Antipattern" usw. sollten sparsam verwendet und mit Argwohn behandelt werden. Sie fördern das Schwarz-Weiß-Denken. Es ist besser, Ihre Urteile im Kontext zu fällen, als nur auf Dogmen zu beruhen. zB etwas, das jemand gesagt hat, ist "Best Practice".
quelle
code smell
es entweder zu verwenden. Das heißt, es ist eine Folge von schlechtem Design-Code (nicht polymorph), der Sie dazu bringt, beide zu verwenden. Kann ich auf diese Weise auf die Verwendung von beiden schließen?instanceof
&getClass()
aufgrund des vorhandenen schlechten Designs (nicht polymorph) des Codes ins Bild kommt. hab ich recht?instanceof
(zum Beispiel) schlechtes Design ist. Es gibt Situationen, in denen dies die beste Lösung sein kann. Gleiches gilt fürgetClass()
. Ich werde wiederholen, dass ich "Überbeanspruchung" und nicht "Verwendung" gesagt habe . Jeder Fall muss nach seinen Vorzügen beurteilt werden ... nicht durch blinde Anwendung einer unbegründeten dogmatischen Regel.Möchten Sie eine Klasse genau zuordnen , z. B. nur eine Übereinstimmung
FileInputStream
anstelle einer Unterklasse vonFileInputStream
? Wenn ja, verwenden SiegetClass()
und==
. Ich würde dies normalerweise in a tunequals
, damit eine Instanz von X nicht gleich einer Instanz einer Unterklasse von X ist - andernfalls kann es zu kniffligen Symmetrieproblemen kommen. Andererseits ist dies normalerweise nützlicher, um zu vergleichen, dass zwei Objekte derselben Klasse angehören als einer bestimmten Klasse.Andernfalls verwenden Sie
instanceof
. Beachten Sie, dassgetClass()
Sie zunächst sicherstellen müssen, dass Sie eine Nicht-Null-Referenz haben, sonst erhalten Sie eineNullPointerException
, währendinstanceof
nur zurückgegeben wird,false
wenn der erste Operand Null ist.Persönlich würde ich sagen, dass
instanceof
es idiomatischer ist - aber eine der beiden ausgiebig zu verwenden, ist in den meisten Fällen ein Designgeruch.quelle
Ich weiß, dass es eine Weile her ist, seit dies gefragt wurde, aber ich habe gestern eine Alternative gelernt
Wir alle wissen, dass Sie Folgendes tun können:
aber was ist, wenn Sie nicht genau wissen, welche Art von Klasse es sein muss? Sie können nicht generisch tun:
da es einen Kompilierungsfehler gibt.
Stattdessen gibt es hier eine Alternative - isAssignableFrom ()
Beispielsweise:
quelle
isAssignableFrom
. Die richtige Art,o instanceof String
mit Reflexion zu schreiben , istString.getClass().isInstance(o)
. Das Javadoc sagt es sogar so: Diese Methode ist das dynamische Äquivalent des Java-instanceof
Sprachoperators.getClass () hat die Einschränkung, dass Objekte nur anderen Objekten derselben Klasse und demselben Laufzeittyp entsprechen, wie in der Ausgabe des folgenden Codes dargestellt:
Ausgänge:
SubClass erweitert ParentClass. subClassInstance ist eine Instanz von ParentClass.
Verschiedene getClass () geben Ergebnisse mit subClassInstance und parentClassInstance zurück.
quelle