(Please don't tell me that I should abstract X and add another method to it.)
In C ++, when I have an X variable of type X* and I want to do something specific, if it also has type Y* ( Y , which is a subclass of X ), I wrote this:
if(Y* y = dynamic_cast<Y*>(x)) {
The same seems impossible in Java (or is it?).
Instead, I read this Java code:
if(x instanceof Y) { Y y = (Y) x;
Sometimes, when you don't have the X variable, but instead it is a more complex expression, just because of this problem you need a dummy variable in Java:
X x = something(); if(x instanceof Y) { Y y = (Y) x; // ... } // x not needed here anymore
(It’s common that something() is iterator.next() . And there you see that you also cannot call it twice. You really need a dummy variable.)
You don’t need X here at all - you just have it because you cannot perform instanceof checking right away with the act. Compare this again with the fairly common C ++ code:
if(Y* y = dynamic_cast<Y*>( something() )) {
In this regard, I introduced the castOrNull function, which avoids the dummy variable X I can write this now:
Y y = castOrNull( something(), Y.class ); if(y != null) {
castOrNull implementation:
public static <T> T castOrNull(Object obj, Class<T> clazz) { try { return clazz.cast(obj); } catch (ClassCastException exc) { return null; } }
Now I have been told that using this castOrNull function castOrNull this way is an evil thing . Why is this? (Or to pose a more general question: would you agree and think that it is evil? If so, why so? Or do you think that this is a real (possibly rare) use case?)
As I said, I don’t want to discuss whether using such a lowering effect is a good idea. But let me briefly explain why I sometimes use it:
Sometimes I get into the case when I have to choose between adding a new method for a very specific thing (which will apply to only one subclass in one particular case) or using such an instanceof check. Basically, I have a choice between adding the doSomethingVeryVerySpecificIfIAmY() function or doing an instanceof check. And in such cases, I feel that the latter is cleaner.
Sometimes I have a collection of some interface / base class and for all entries of type Y , I want to do something and then remove them from the collection. (For example, I had a case where I had a tree structure and wanted to remove all child elements that are empty leaves.)