Either the bytecode is executed normally, or it executes the given commands, or jvm rejects them.
I played with programming directly in the java byte codec some time ago using jasmin , and I noticed some things.
If the bytecode you edited makes sense, it will work as expected. However, there are some bytecode patterns that are rejected with VerifyError.
For a specific example of access outside of access, you can compile code with outside limits just fine. They will bring you an ArrayIndexOutOfBoundsException at runtime.
int[] arr = new int[20]; for (int i = 0; i < 100; i++) { arr[i] = i; }
However, you can build bytecode, which is a more fundamental flaw than this. To give an example, I will first explain some things.
The java bytecode works with stack , and the instructions work with the top elements on the stack.
The stack naturally has different sizes in different places in the program, but sometimes you can use goto in the bytecode to make the stack look different depending on how you got there.
The stack can contain object, int , then you store the object in an array of objects and int in an array of int. Then you continue and from somewhere else in this bytecode you use goto, but now your stack contains int, object , which will cause int to be passed to an array of objects and vice versa.
This is just one example of what might happen, making your bytecode fundamentally wrong. The JVM detects these flaws when the class is loaded at run time, and then throws a VerifyError if something does not work.