Java Class.isAssignableFrom(Class) 与 instanceof 的区别

superClass.isAssignableFrom(childClass) 属于 Class.java。它的对象和参数都是类,意思是“父类(或接口类)判断给定类是否是它本身或其子类”。我们看一下它的源码

public boolean isAssignableFrom(Class c) {
   if (this == c) {
     //如果两个类是相同的,那么直接返回真
        return true;  // Can always assign to things of the same type.
    } else if (this == Object.class) {
     //如果当前类是Object,那么只要判断给定的类是不是基本数据类型(原始数据类型)即可
        return !c.isPrimitive();  // Can assign any reference to java.lang.Object.
    } else if (isArray()) {
        //如果当前类是数组,那么给定类也必须是数组。然后再将它们的数组类型进行比较
        return c.isArray() && componentType.isAssignableFrom(c.componentType);
    } else if (isInterface()) {
        //如果当前类是接口,那么就获取给定类的接口列表,只要给定类中存在某个接口类型为当前类,则返回true
        // Search iftable which has a flattened and uniqued list of interfaces.
        Object[] iftable = c.ifTable;
        if (iftable != null) {
            for (int i = 0; i < iftable.length; i += 2) {
                if (iftable[i] == this) {
                    return true;
                }
            }
        }
        return false;
    } else {
        if (!c.isInterface()) {
            //如果不是接口,而是自定义类型,则不断的通过获取父类来判断
            for (c = c.superClass; c != null; c = c.superClass) {
                if (c == this) {
                    return true;
                }
            }
        }
        return false;
    }
}

/*
 * Java中的9种基本数据类型(原始数据类型)
 *
 * @see     java.lang.Boolean#TYPE
 * @see     java.lang.Character#TYPE
 * @see     java.lang.Byte#TYPE
 * @see     java.lang.Short#TYPE
 * @see     java.lang.Integer#TYPE
 * @see     java.lang.Long#TYPE
 * @see     java.lang.Float#TYPE
 * @see     java.lang.Double#TYPE
 * @see     java.lang.Void#TYPE
 * @since JDK1.1
 */
public boolean isPrimitive() {
  return (primitiveType & 0xFFFF) != 0;
}

/*
 * 判断当前类是否是接口
 */
public boolean isInterface() {
  return (accessFlags & Modifier.INTERFACE) != 0;
}

至于 instanceof,我看不到他的源码。但是知道它的原型是 childObj instanceof superT,也就是说它左右的参数均是对象实例,意思是“给定类的实例是否是某个类的子类”。

看一个例子,这个例子我通过Android Studio 的 UnitTest 来演示

public class ExampleUnitTest {

    class SuperClass {}
    class ChildClass extends SuperClass{}

    @Test
    public void assignable_test_1() throws Exception {//true
        assertTrue(SuperClass.class.isAssignableFrom(ChildClass.class));
    }
    @Test
    public void assignable_test_2() throws Exception {//true
        assertTrue(SuperClass.class.isAssignableFrom(SuperClass.class));
    }
    @Test
    public void assignable_test_3() throws Exception {//false
        assertTrue(ChildClass.class.isAssignableFrom(SuperClass.class));
    }
    @Test
    public void instanceof_test_1() throws Exception {//false
        SuperClass sup = new SuperClass();
        assertTrue(sup instanceof ChildClass);
    }
    @Test
    public void instanceof_test_2() throws Exception {//true
        SuperClass sup = new SuperClass();
        assertTrue(sup instanceof SuperClass);
    }
    @Test
    public void instanceof_test_3() throws Exception {//true
        ChildClass child = new ChildClass();
        assertTrue(child instanceof ChildClass);
    }
}

Java Class.isAssignableFrom(Class) 与 instanceof 的区别_第1张图片

总结:可以看到 isAssignableFrom 和 instanceof 都是用来判断两个类的继承关系的,只是作用的对象不一样。前面的那个是作用在类上,后面的那个是作用在类的实例上。

你可能感兴趣的:(Java)