For some reason, common perception is that using
instanceof is a bit of smell. I think its fallen in with a bad crowd and isn’t really as bad as its cracked up to be. At the very least, we should consider why its got a bad reputation.
For example, given the following, what’s clearer in the following exception handling code?
There seems very little difference in the semantics of the two calls, both handle class hierarchies and both handle interfaces. I think the legitimate use for
Class.isAssignableFrom is around scenarios where reflective-type checks are more suited (for example, where the class to check against is only known or may change at runtime). Using
Class.isInstance is a similar alternative. The other point that the API documentation points out is that
isAssignableFrom works with primitives whereas
instanceof can not.
instanceof is seen as a bit antiquated but given the example above using
Class.isAssignableFrom seems to just obfuscate things. The example needs to find out why a dynamic proxy throws an exception and because the InvocationTargetException wraps the underlying cause, it kind of breaks checked exception handling and it feels like we need to do some conditional check. If there is a smell here, that’s it. The above is trying to hide the symptom of the smell (
instanceof) but the smell is still there, its just harder to see. I often catch similar whiffs when catching ExecutionException.
More conventional cases where
instanceof is a genuine smell may be around conditional logic making decisions based on class type where using polymorphism might be a better solution.