如何在JVM中实现'instanceof'?

时间:2013-10-05 14:57:41

标签: java jvm instanceof

它是否使用反射,如果是,那么幕后会发生什么?

2 个答案:

答案 0 :(得分:11)

Jon对于运算符如何映射到字节码是正确的。就实现而言,大多数JVM将内存中的对象表示为已加载的具体类的tagged unions

  

标记联合,也称为变体,变体记录,区分联合,不相交联合或求和类型,是用于保存可以采用多种不同但固定类型的值的数据结构。

因此,当具体类型是类类型的实例时,可以通过查看具有位设置的sparse boolean matrix来回答x instanceof MyClassType

x instanceof InterfaceType有点棘手,但类似的方法也可以帮助解决这个问题。

JVM可以在内存中保留一个大的稀疏矩阵,每个标称类型(类或接口类型)有一行,每个类类型有一列。

例如:

                           [all nominal types]
                     Object String Integer Number Comparable Iterable ...
[only       String   ✓      ✓                     ✓
 concrete   Integer  ✓             ✓       ✓      ✓
 types]     ...

当JVM必须垃圾收集类时,维护这个矩阵变得更加棘手,所以你通常会用类对象存储一行。


Proxy classes是一个有趣的角落案例,但我最好的猜测是代理类定义涉及在运行时生成一些字节码,然后通过大多数JVM中的普通类加载系统。

答案 1 :(得分:9)

它是JVM指令集的一部分,基本上 - 有一个特定的instanceof指令。例如,像这样的方法:

public static void checkString(Object x) {
    if (x instanceof String) {
        System.out.println("Foo");
    }
}

编译成:

public static void checkString(java.lang.Object);
  Code:
     0: aload_0
     1: instanceof    #2                  // class java/lang/String
     4: ifeq          15
     7: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
    10: ldc           #4                  // String Foo
    12: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    15: return
}

(这只是javap的输出。)

JVM specification详细说明了指令的作用。有关指令的确切详细信息,请参阅section 6.5。它的实现方式取决于VM的实现 - 但是一个示例实现可能是:

  • 检查第一个操作数是否为null(如果是,则返回false
  • 查找第一个操作数引用的对象的执行时类型。
  • 向上导航类型层次结构(包括已实现的接口),直到您可以证明实际类型与第二个操作数兼容或不兼容。