Instanceof против эквивалентности объектов Class
При получении информации о типе существует важное различие между любой формой instanceof (это instanceof либо isInstance(), которые приводят к одинаковым результатам) и прямым сравнением объектов Class. Вот пример, демонстрирующий эту разницу:
//: c12:FamilyVsExactType.java // Разница между instanceof и class
class Base {} class Derived extends Base {}
public class FamilyVsExactType { static void test(Object x) { System.out.println("Testing x of type " + x.getClass()); System.out.println("x instanceof Base " + (x instanceof Base)); System.out.println("x instanceof Derived " + (x instanceof Derived)); System.out.println("Base.isInstance(x) " + Base.class.isInstance(x)); System.out.println("Derived.isInstance(x) " + Derived.class.isInstance(x)); System.out.println( "x.getClass() == Base.class " + (x.getClass() == Base.class)); System.out.println( "x.getClass() == Derived.class " + (x.getClass() == Derived.class)); System.out.println( "x.getClass().equals(Base.class)) " + (x.getClass().equals(Base.class))); System.out.println( "x.getClass().equals(Derived.class)) " + (x.getClass().equals(Derived.class))); } public static void main(String[] args) { test(new Base()); test(new Derived()); } } ///:~
Метод test( ) выполняет проверку типа, используя обе формы instanceof. Затем получает ссылку на объект Class и использует выражение "==" и equals( ) для проверки эквивалентности объектов Class. Вот результаты:
Testing x of type class Base x instanceof Base true x instanceof Derived false Base.isInstance(x) true Derived.isInstance(x) false x.getClass() == Base.class true x.getClass() == Derived.class false x.getClass().equals(Base.class)) true x.getClass().equals(Derived.class)) false Testing x of type class Derived x instanceof Base true x instanceof Derived true Base.isInstance(x) true Derived.isInstance(x) true x.getClass() == Base.class false x.getClass() == Derived.class true x.getClass().equals(Base.class)) false x.getClass().equals(Derived.class)) true
Конечно, instanceof и isInstance( ) выдают абсолютно идентичные результаты, также как и equals( ) и "==". Однако, исход работы разный. В общем представлении типа, instanceof говорит, “является ли объект этим классом, либо наследником этого класса?” С другой стороны, если Вы сравниваете объекты Class, используя "==", наследование не имеет значения, это либо точно такой же тип, либо нет.