Does it use reflectione, and if so, what's going on behind the scenes?
instanceof is a binary operator we use to test if an object is of a given type. The result of the operation is either true or false. It's also known as a type comparison operator because it compares the instance with the type. Before casting an unknown object, the instanceof check should always be used.
The primary alternative to using instanceof is polymorphism. Rather then ask which type of object you have at the current position you tell the object, whatever it is, to do what you want done. If both objects know how to do that then this works fine, even if they do it differently.
The java instanceof operator is used to test whether the object is an instance of the specified type (class or subclass or interface). The instanceof in java is also known as type comparison operator because it compares the instance with type. It returns either true or false.
Jon is right about how the operator maps to byte-code. As far as implementations, most JVMs represent objects in memory as tagged unions of the loaded concrete classes:
a tagged union, also called a variant, variant record, discriminated union, disjoint union, or sum type, is a data structure used to hold a value that could take on several different, but fixed types.
So x instanceof MyClassType
can be answered by looking at a sparse boolean matrix that has a bit set when a concrete type is an instance of a class type.
x instanceof InterfaceType
is a bit trickier but similar methods can help with that too.
The JVM can keep a large sparse matrix in memory with a row per nominal types (class or interface types) and a column per class type.
For example:
[all nominal types]
Object String Integer Number Comparable Iterable ...
[only String ✓ ✓ ✓
concrete Integer ✓ ✓ ✓ ✓
types] ...
When the JVM has to garbage collect classes, maintaining this matrix becomes trickier, so you usually store a row with the class object.
Proxy classes are an interesting corner case but my best guess is that proxy class definition involves generating some byte-code at runtime that then goes through the normal class loading system in most JVMs.
It's part of the JVM instruction set, basically - there's a specific instanceof
instruction. So for example, a method like this:
public static void checkString(Object x) {
if (x instanceof String) {
System.out.println("Foo");
}
}
is compiled into:
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
}
(That's just the output of javap
.)
The JVM specification has details of what the instruction has to do. See section 6.5 for exact details of the instruction. How it's implemented is up to the VM implementation - but one sample implementation could be:
null
(and return false
if so)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With