Conventional wisdom says you can only throw objects that extend Throwable in Java, but is it possible to disable the bytecode verifier and get Java to compile and run code that throws arbitrary objects – or even primitives?
I looked up the JVM’s athrow and it will pop the first objref on the operand stack; but would it check if said reference points to a Throwable at run time?
It depends on your JVM implementation. According to the Java VM specification it is undefined behavior if the object is not
Throwable.In section 6.1, “The Meaning of ‘Must'”:
I wrote a test program using the Jasmin assembler which does the equivalent of
throw new Object(). The Java HotSpot Server VM throws aVerifyError:Disabling the bytecode verifier allows the
athrowto execute and the JVM appears to crash when it tries to print the exception’s details. Compare these two programs, the first which throws anException, the second which is the above test program which throws anObject. Notice how it exits in the middle of a printout:Of course, disabling the bytecode verifier is dangerous. The VM proper is written to assume that bytecode verification has been performed and therefore does not have to typecheck instruction operands. Beware: the undefined behavior that you invoke when you circumvent bytecode verification is much like the undefined behavior in C programs; anything at all can happen, including demons flying out of your nose.