Java bytecode

[1] Each instruction is represented by a single byte, hence the name bytecode, making it a compact form of data.

Each frame for a method call has an "operand stack" and an array of "local variables".

[5]: 2.6  [2] The operand stack is used for passing operands to computations and for receiving the return value of a called method, while local variables serve the same purpose as registers and are also used to pass method arguments.

The maximum size of the operand stack and local variable array, computed by the compiler, is part of the attributes of each method.

If executing bytecode in a virtual machine is undesirable, a developer can also compile Java source code or bytecode directly to native machine code with tools such as the GNU Compiler for Java (GCJ).

The Java virtual machine provides some support for dynamically typed languages.

Most of the extant JVM instruction set is statically typed - in the sense that method calls have their signatures type-checked at compile time, without a mechanism to defer this decision to run time, or to choose the method dispatch by an alternative approach.

[12] JSR 292 (Supporting Dynamically Typed Languages on the Java Platform)[13] added a new invokedynamic instruction at the JVM level, to allow method invocation relying on dynamic type checking (instead of the extant statically type-checked invokevirtual instruction).