Ugly But Proud: the instanceof operator

Ah the unlovely instanceof operator — that poor cousin of the reflection API and redheaded stepchild of Java’s object-oriented programming model — does it have no friends in this world? Was it brought forth from the depths of James Gosling‘s mind only to instigate mass hackishness? If you’ve read almost any book on Java programming, you’ve no doubt been warned repeatedly that use of instanceof is a warning sign on the road to BAD OBJECT ORIENTED DESIGN. The accusation does have its merits. Abuse of instanceof can often be a lazy man’s stand-in for a more properly thought out use of polymorphism. But we should not be so hasty to throw stones at this humble and venerable Java language feature. instanceof is not evil, it’s simply misunderstood.

The type of example often used in warning young programmers away from instanceof goes something like this:

public void doSomething(MyClass obj) {
  if(obj instanceof MyClassDescendant1) {
    // take one path...
  } else if (obj instanceof MyClassDescendant2) {
    // take another path...
  } else if (obj instanceof MyClassDescendant3) {
    // take a third path...
  }
}

Clearly, if we had instead declared the doSomething() method as a member of MyClass and allowed subclasses to simply override the method as needed to specialize the behavior, then we could have the much cleaner:

// using a factory simply to illustrate that
// we don't know what the actual instance type is
MyClass obj = MyClassFactory().newMyClass();

// the appropriate subclass method is executed
obj.doSomething();

So one should avoid using instanceof to select behavior based on object type when polymorphism could do that in a much cleaner way. But if you’ve spent any time programming in Java, then you’ve seen that instanceof is commonly used. Often it’s abused, but sometimes it’s used with good reason. So, what are the guidelines for its proper use?

1. Use instanceof for parameter checking. For example, if you’re overriding Object.equals() in one of your own classes, a common first part of such a method is to write:

public MyClass {
  // ...
  public boolean equals(Object o1) {
    if(!(o1 instanceof MyClass)) {
      return false;
    }
    // rest of method...
  }
}

2. Use instanceof when you are obliged to program to an interface that involves objects typed as one of those empty “marker” interfaces as parameters. A perfect example can be found by looking at the javax.security.auth.callback.CallbackHandler interface. If you endeavor to implement this interface, you will quickly find yourself using instanceof, since the single parameter to the handle() method is an array of Callback objects, and Callback is an empty interface.

Leave a Reply

Your email address will not be published. Required fields are marked *