Despite all this careful checking, some kinds of safety requirements cannot be statically verified. These have to be checked when the instruction is executed. This does not decrease the security of the Java virtual machine; it only moves some of the checking from loadtime to runtime.
Some of the requirements checked when the program is run are:
When the instructions notice that the program has failed to meet one of these requirements, an exception is thrown. This prevents the instruction from executing invalidly.
The last requirement supports an oddity in the JVM type system when it comes to arrays. Programmers expect that an array of Strings is a subclass of an array of Objects. This is legal in Java, and the JVM equivalent is also legal:
Object array = new String; Object o = array;
This matches the programmer's intuition that an array of Strings holds things that are Objects. However, array doesn't behave exactly like an Object: you can't store non-String objects into it:
array = new Integer(9);
This causes the program to throw an ArrayStoreException. If it were allowed to succeed, then there would be an Integer in an array that should hold only Strings. In the JVM code, this exception is thrown by the aastore instruction.