The difference between Java Class. isAssignable From (Class) and instanceof

Keywords: Java Android

SupClass. isAssignableFrom (childClass) belongs to Class.java. Its objects and parameters are classes, meaning "parent class (or interface class) determines whether a given class is itself or its subclass". Let's take a look at its source code.

public boolean isAssignableFrom(Class<?> c) {
   if (this == c) {
     //If the two classes are the same, return the true directly
        return true;  // Can always assign to things of the same type.
    } else if (this == Object.class) {
     //If the current class is Object, then just decide whether the given class is a basic data type (original data type)?
        return !c.isPrimitive();  // Can assign any reference to java.lang.Object.
    } else if (isArray()) {
        //If the current class is an array, then the given class must also be an array. Then compare their array types
        return c.isArray() && componentType.isAssignableFrom(c.componentType);
    } else if (isInterface()) {
        //If the current class is an interface, get a list of interfaces for a given class, and return true as long as there is an interface type in the given class that is the current class.
        // 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()) {
            //If it's not an interface, but a custom type, it's constantly judged by acquiring the parent class
            for (c = c.superClass; c != null; c = c.superClass) {
                if (c == this) {
                    return true;
                }
            }
        }
        return false;
    }
}

/*
 * Java 9 basic data types (original data types)
 *
 * @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;
}

/*
 * Determine whether the current class is an interface?
 */
public boolean isInterface() {
  return (accessFlags & Modifier.INTERFACE) != 0;
}

As for instanceof, I can't see his source code. But we know that its prototype is child Obj instance of superT, that is to say, the parameters around it are object instances, which means "whether an instance of a given class is a subclass of a class".

Let's look at an example, which I demonstrated through Unit Test of Android Studio

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);
    }
}

Summary: We can see that isAssignableFrom and instanceof are used to judge the inheritance relationship between the two classes, but the objects are different. The first one is on the class, and the second one is on the instance of the class.

Posted by jefffan24 on Wed, 13 Feb 2019 14:12:18 -0800