instanceOf、isInstance、isAssignableFrom 的区别
在 Java 中,对一个类的子类判断有三种方式,分别是 obj instanceof [TypeName]、class.isInstance(obj)、class.isAssignableFrom(class),他们的作用都是进行父子类型判断,然而他们的区别又在什么地方。
- 
其中
instanceof是一个 Java 原语,通过对象与类型签名进行判断,需要在编译期就进行解析成字节码。跟进 JVM 源码里,在templateTable.hpp中发现了 instanceof 方法的定义,从其中templateTable_x86.cpp、templateTable_arm.cpp的instanceof方法可得,其实现方式主要是通过汇编指令从 klass 中获取标记进行判断,逻辑比较长也就不一一分析了。对于这段冗长的汇编代码,JVM 也进行了优化,当触发 JIT 编译时,会把这段逻辑编译成机器码写入 C1 层。 - 
isInstance是 Class 类下的 native 方法,接收参数为对象。分析了在jni.cpp中的大体流程,程序先通过 class 获取到 Klass,调用 object 内 klass 的is_subtype_of方法,传入方才获取的 Klass,判断二者地址是否相同,是则判定为同一类型,否则再调用search_secondary_supers,判断父级类型是否存在与传入的 Klass 相匹配。 
JNI_QUICK_ENTRY(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
  JNIWrapper("IsInstanceOf");
  HOTSPOT_JNI_ISINSTANCEOF_ENTRY(env, obj, clazz);
  jboolean ret = JNI_TRUE;
  if (obj != NULL) {
    ret = JNI_FALSE;
    Klass* k = java_lang_Class::as_Klass(
      JNIHandles::resolve_non_null(clazz));
    if (k != NULL) {
      ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;
    }
  }
  HOTSPOT_JNI_ISINSTANCEOF_RETURN(ret);
  return ret;
JNI_END
// hotspot/share/oops/oop.inline.hpp
bool oopDesc::is_a(Klass* k) const {
  return klass()->is_subtype_of(k);
}
// hotspot/share/oops/klass.hpp
// subtype check: true if is_subclass_of, or if k is interface and receiver implements it
bool is_subtype_of(Klass* k) const {
  juint    off = k->super_check_offset();
  Klass* sup = *(Klass**)( (address)this + off );
  const juint secondary_offset = in_bytes(secondary_super_cache_offset());
  if (sup == k) {
    return true;
  } else if (off != secondary_offset) {
    return false;
  } else {
    return search_secondary_supers(k);
  }
}
bool Klass::search_secondary_supers(Klass* k) const {
  // Put some extra logic here out-of-line, before the search proper.
  // This cuts down the size of the inline method.
  // This is necessary, since I am never in my own secondary_super list.
  if (this == k)
    return true;
  // Scan the array-of-objects for a match
  int cnt = secondary_supers()->length();
  for (int i = 0; i < cnt; i++) {
    if (secondary_supers()->at(i) == k) {
      ((Klass*)this)->set_secondary_super_cache(k);
      return true;
    }
  }
  return false;
}
isAssignableFrom也是 Class 类下的 native 方法,接收参数为 Class 类。主要逻辑与isInstance相同,区别在于当 主体 Class 与 参数 Class 其中一个为原生类型时,则选择使用对象头判断类型是否相等。
isInstance 和 isAssignableFrom 对入参校验上也有区别,isInstance 当对象为空时将会返回 false isAssignableFrom 则会对参数进行非空校验。
isInstance 和 isAssignableFrom 在方法标记上都有 @HotSpotIntrinsicCandidate,会被 JVM 使用更高效的字节码替换,节省了 JNI 调用的开销。
JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
  JNIWrapper("IsSubclassOf");
  HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(env, sub, super);
  oop sub_mirror   = JNIHandles::resolve_non_null(sub);
  oop super_mirror = JNIHandles::resolve_non_null(super);
  if (java_lang_Class::is_primitive(sub_mirror) ||
      java_lang_Class::is_primitive(super_mirror)) {
    jboolean ret = oopDesc::equals(sub_mirror, super_mirror);
    HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
    return ret;
  }
  Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
  Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
  assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
  jboolean ret = sub_klass->is_subtype_of(super_klass) ?
                   JNI_TRUE : JNI_FALSE;
  HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
  return ret;
JNI_END
总结一下,instanceof、isInstance、isAssignableFrom 其实无太大区别,instanceof 和 isInstance 适用于主体是对象,并且 instanceof 需要在编译期就指定类型,灵活性不如 isInstance。而 isAssignableFrom 是针对两个类的关系校验,在泛型对比上比较适合。