它是否使用反射,如果是,那么幕后会发生什么?
答案 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
)