In general, a good solution to avoid instanceof is to use a so-called visitor pattern .
For this template, you need an additional interface (visitor), its implementation containing the code you want to execute, and an additional method in all classes of your hierarchy, so this can be excessive in small cases (but it is very convenient if there is not only A and B , but also more types).
In your case, it will look like this:
interface Visitor { void visit(A a); void visit(B b); } class Base { abstract accept(Visitor v); } class A extends Base { accept(Visitor v) { v.visit(this); } } class B extends Base { accept(Visitor v) { v.visit(this); } } class MyVisitor implements Visitor { visit(A a) { doSomethingWithA(a); } visit(B b) { doSomethingWithB(b); } }
It is used as follows:
MyVisitor v = new MyVisitor(); while(iterator.hasNext()) { Base next = iterator.next(); next.accept(v); }
The advantage is that you should write most of the code only once. If you want to do other things with A and B elsewhere in your program, just write a different version of Visitor. You do not need to modify Base , A and B in the same way as if you added doSomething() to these classes.
Edit: If the number of subclasses increases, you need to change all existing Visitor implementations. However, at least the compiler talks about this. With instanceof you can forget the place where you need to add a processing clause. This may not be detected at run time, while the visitor pattern gives you security at compile time.
source share