(Si prega di non consigliare che avrei dovuto astratto più X
e aggiungere un altro metodo per esso.)java: combinazione di instanceof e cast?
In C++, quando ho una variabile x
di tipo e voglio fare qualcosa di specifico, se è anche di tipo Y*
(Y
essendo una sottoclasse di X
), sto scrivendo questo: (? o è)
if(Y* y = dynamic_cast<Y*>(x)) {
// now do sth with y
}
La stessa cosa non sembra possibile in Java.
Ho letto questo codice Java invece:
if(x instanceof Y) {
Y y = (Y) x;
// ...
}
A volte, quando non si dispone di una variabile x
ma è un'espressione più complessa, invece, proprio a causa di questo problema, è necessario una variabile dummy in Java:
X x = something();
if(x instanceof Y) {
Y y = (Y) x;
// ...
}
// x not needed here anymore
(cosa comune è che something()
è iterator.next()
E ci si vede che anche voi non si può davvero chiamare che solo due volte Hai davvero bisogno la variabile fittizia...)
Non hai davvero bisogno di x
qui - lo hai solo perché non puoi fare il controllo instanceof
in una sola volta con il cast. Confronti che, ancora una volta per il codice abbastanza comune C++:
if(Y* y = dynamic_cast<Y*>(something())) {
// ...
}
A causa di questo, ho introdotto una funzione castOrNull
, che permette di evitare la variabile dummy x
. Posso scrivere questo ora:
Y y = castOrNull(something(), Y.class);
if(y != null) {
// ...
}
Attuazione castOrNull
:
public static <T> T castOrNull(Object obj, Class<T> clazz) {
try {
return clazz.cast(obj);
} catch (ClassCastException exc) {
return null;
}
}
Ora, mi hanno detto che using this castOrNull
function in that way is an evil thing do to. Perché? (O, per dirla alla questione più generale: Lei è d'accordo e anche che questo è il male Se sì, perché così O pensi che questo sia un valido (forse raro) caso d'uso???)
Come detto , Non voglio una discussione se l'uso di tale downcast sia una buona idea. Ma lasciatemi chiarire brevemente il motivo per cui a volte lo uso:
A volte mi trovo in caso in cui devo scegliere tra l'aggiunta di un altro nuovo metodo per una cosa molto specifico (che si applicherà solo per un singolo sottoclasse in uno caso specifico) o utilizzando tale controllo
instanceof
. Fondamentalmente, ho la scelta tra l'aggiunta di una funzionedoSomethingVeryVerySpecificIfIAmY()
o il controlloinstanceof
. E in questi casi, sento che quest'ultimo è più pulito.A volte ho una raccolta di alcune interfacce/classe base e per tutte le voci di tipo
Y
, voglio fare qualcosa e quindi rimuoverle dalla raccolta. (Ad esempio, ho avuto il caso in cui ho avuto una struttura ad albero e volevo cancellare tutte bambino che sono foglie vuote.)
userei _instanceOf_ invece di _class.cast_ al fine di evitare inutili eccezioni in _castOrNull_, ma a parte che ti sembra di avere perfettamente normale aiutante. Lascia che ** Tom ** chiarisca cosa intendeva. –
Se Y è un _superclass_ di X, non hai bisogno di alcun cast - intendevi _subclass_? –
Anche se questo non è un one-liner in Java, le prestazioni di instanceof e casting sono abbastanza buone. Inserisco un po 'di tempo in Java7 su diversi approcci al problema qui: http://stackoverflow.com/questions/16320014/java-optimization-nitpick-is-it-faster-to-cast-something-and-let-it- throw-excep/28858680 # 28858680 – Wheezil