The checkcast exception checks to see if an object has the appropriate type. If it succeeds, it leaves the reference to the object on the stack. If it fails, it throws a ClassCastException.
Sometimes you want to check the type of something without having it throw an exception if you guess wrong. In this case, use the instanceof instruction. It works much like checkcast, except that instead of throwing an exception in the case of failure, the JVM leaves a 1 or 0 on top of the stack indicating success or failure.
For example, suppose you have three classes, Larry, Curly, and Moe, each of which has Stooge as a superclass.
; Get a random stooge invokevirtual Movies/getStooge()LStooge; dup ; Copy the reference instanceof Curly ; Is it Curly? ifeq notCurly ; If the result is 0, go to notCurly ; Now we know that the top of the stack must be Curly checkcast Curly ; Let the machine know about that ;; Do whatever it is you want with Curly return notCurly: ;; Deal with Larry or Moe return
If the stooge you get is a Curly, then the instanceof operator will leave 1 on the stack; otherwise, it will leave 0. The ifeq instruction goes to notCurly if the value on top of the stack is equal to 0. Otherwise, it will continue at the next instruction as usual.
Unlike checkcast, the instanceof instruction removes its operand from the stack, so you have to dup it if you want to use the reference that is being tested. The JVM doesn't use the information from the instanceof to change what it knows about the dup, so you still have to use checkcast if you want to use the object as an instance of the type.