В Java доступны три способа проверки совместимости типов. Функционально они ничем не отличаются, применяются для разных наборов аргументов. В порядке убывания
быстродействия:
instanceof – бинарный оператор, самый быстрый и самый используемый. Если есть экземпляр
A и можно указать
B явно, выбирать надо его. Если
A (точнее тип хранящей экземпляр
A переменной) и
B не из одной цепочки наследования – экземпляр точно не может быть подтипом
B и компиляция упадет с ошибкой
inconvertible types.
Class::isInstance – метод принимает параметром объект типа A. Его стоит выбрать, когда экземпляр
A в наличии, но
B – неизвестный на этапе компиляции тип. То есть, для переменных
A a и
Class bClass, можем проверить
bClass.isInstance(a).
Class::isAssignableFrom – принимает
Class<A>. Единственное, что остается, если экземпляра
A нет.
bClass.isAssignableFrom(aClass).
Есть еще четвертый способ – имея экземпляр типа
A привести его к
B. Если типы были несовместимы, приведение выбросит
ClassCastException. Это во всех смыслах плохой способ, построению логики программы на исключениях нет оправдания. Подробная аргументация описана в
Effective Java Item 57.