2013-10-05 29 views

回答

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
  • 找对象的执行时间类型第一个操作数指的是。
  • 向上浏览类型层次结构(包括已实现的接口),直到证明实际类型与第二个操作数兼容或不兼容。
9

Jon对于运算符如何映射字节码是正确的。至于实施方式中,大多数JVM代表内存中对象的加载的具体类的tagged unions

一个标签联合,也称为一个变型,变体记录,识别联合,不相交并,或总和类型,是数据结构用于保存可能采用几种不同但固定类型的值。

所以x instanceof MyClassType可以通过看一个sparse boolean matrix具有位集时的具体类型是类类型的实例来回答。

x instanceof InterfaceType有点棘手,但类似的方法也可以帮助。

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

例如:

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

当JVM有垃圾收集类,保持这个矩阵变得棘手,所以通常存储一排类对象。


Proxy classes是一个有趣的极端情况,但我最好的猜测是,代理类的定义包括生成在运行时的一些字节代码,然后通过在大多数JVM正常类加载系统进入。