(Bitte nicht darauf hinweisen, dass ich soll abstrakt X
mehr und eine andere Methode, um es hinzuzufügen.)Java: Kombination von instanceof und cast?
In C++, wenn ich eine Variable x
vom Typ habe, und ich will etwas Bestimmtes tun, wenn es Art auch von Y*
ist (Y
ist eine Unterklasse von X
), ich schreibe dies: (? oder ist es)
if(Y* y = dynamic_cast<Y*>(x)) {
// now do sth with y
}
Das gleiche scheint nicht möglich, in Java.
ich diesen Java-Code stattdessen gelesen haben:
if(x instanceof Y) {
Y y = (Y) x;
// ...
}
Manchmal, wenn Sie es nicht eine Variable x
haben, sondern ist ein komplexer Ausdruck stattdessen nur wegen dieses Problems, müssen Sie eine Dummy-Variable in Java:
X x = something();
if(x instanceof Y) {
Y y = (Y) x;
// ...
}
// x not needed here anymore
(Gemeinsame Sache ist, dass something()
ist iterator.next()
Und da sehen Sie, dass Sie auch nicht wirklich, dass zweimal nur anrufen können Sie wirklich das Dummy-Variable benötigen...)
Sie brauchen nicht wirklich x
hier - Sie haben es nur, weil Sie nicht sofort die instanceof
Prüfung mit der Besetzung tun können. Vergleichen Sie das wieder auf die recht häufig C++ Code:
if(Y* y = dynamic_cast<Y*>(something())) {
// ...
}
Aus diesem Grund habe ich eingeführt, um eine castOrNull
Funktion, die es ermöglicht, die Dummy-Variable x
zu vermeiden. Das kann ich jetzt schreiben:
Y y = castOrNull(something(), Y.class);
if(y != null) {
// ...
}
Implementierung von castOrNull
:
public static <T> T castOrNull(Object obj, Class<T> clazz) {
try {
return clazz.cast(obj);
} catch (ClassCastException exc) {
return null;
}
}
Nun, ich wurde gesagt, dass using this castOrNull
function in that way is an evil thing do to. Warum das? (Oder die Frage stellen allgemein: Würden Sie zustimmen, und denkt auch, dieses Übel ist Wenn ja, warum so Oder denken Sie, dies ein gültiger ist (vielleicht selten) Fall benutzen??)
Wie gesagt Ich möchte keine Diskussion darüber, ob die Verwendung von solchen Downcast überhaupt eine gute Idee ist. Aber lassen Sie mich kurz erklären, warum ich es manchmal verwenden:
Manchmal habe ich in den Fall, wo ich zwischen dem Hinzufügen einer weitere neue Methode für eine ganz bestimmte Sache zu wählen (die nur für eine einzige Unterklasse in einem gelten Fall) oder unter Verwendung einer solchen
instanceof
Prüfung. Grundsätzlich habe ich die Wahl zwischen dem Hinzufügen einer FunktiondoSomethingVeryVerySpecificIfIAmY()
oder deminstanceof
Check. Und in solchen Fällen fühle ich, dass letzteres sauberer ist.Manchmal habe ich eine Sammlung von einigen Schnittstelle/Basisklasse und für alle Einträge des Typs
Y
möchte ich etwas tun und dann aus der Sammlung entfernen. (Zum Beispiel hatte ich den Fall, in dem ich eine Baumstruktur hatte, und ich wollte alle Childs löschen, die leer sind Blätter.)
würde ich statt _class.cast_ verwenden _instanceOf_, um unnötige Ausnahmen in _castOrNull_ zu vermeiden, aber abgesehen davon, dass Sie scheinen völlig normal Helfer zu haben. Lass Tom klarstellen, was er meinte. –
Wenn Y eine _superclass_ von X ist, brauchst du überhaupt keine Besetzung - meinst du _subclass_? –
Während dies in Java kein Einliner ist, ist die Leistung von instanceof und casting ziemlich gut. Ich poste etwas Zeit in Java7 um verschiedene Annäherungen an das Problem hier: http://stackoverflow.com/questions/16320014/java-optimization-nitpick-is-it-faster-to-cast-etwas-und-le-it-it- throw-excep/28858680 # 28858680 – Wheezil