How it works
The explanation, with examples you can run.
What a class file holds
A class file is a binary format fixed by the JVMS. It starts with a magic number and a version (Java 21 writes major version 65), then a constant pool that holds every name, type descriptor and literal the class uses, then the fields and methods. Each method body is a Code attribute: the bytecode itself, the maximum depth of its operand stack, the number of local variable slots, and an exception table saying which instructions each catch covers.
A stack machine
Take a tiny method:
public class Add { static int add(int a, int b) { return a + b; } public static void main(String[] args) { System.out.println(add(2, 3)); }}Compile it and disassemble it with javac Add.java && javap -c Add:
static int add(int, int); Code: 0: iload_0 // push local 0 (a) 1: iload_1 // push local 1 (b) 2: iadd // pop two ints, push the sum 3: ireturn // return the int on top of the stackEvery method call gets a frame with two parts: an array of local variables (arguments first, this in slot 0 for instance methods) and an operand stack. Instructions are typed (iadd for ints, ladd for longs, aload for references), which lets the verifier prove before the code runs that no instruction gets a value of the wrong type. In main you will also see invokestatic and invokevirtual, two of the five call instructions; the others are invokespecial (constructors, private and super calls), invokeinterface and invokedynamic.
invokedynamic
invokedynamic lets the first call at a site ask a bootstrap method what to link it to. javac uses it for lambdas and, since Java 9, for string concatenation: "hi " + name compiles to a call to makeConcatWithConstants, so the JDK can improve how strings are joined without anyone recompiling.
Specified versus implemented
The JVMS defines the class file format, the instruction set, verification, and the rules for loading, linking and initialising classes. It deliberately says nothing about how fast any of that happens. Interpreting, compiling to machine code, the object layout in memory and the garbage collector are all choices of the implementation. In practice that implementation is almost always HotSpot, the JVM in OpenJDK and Oracle's JDK; Eclipse OpenJ9 and GraalVM are others. When later topics mention -XX: flags, they are HotSpot's, not Java's.
Because the contract is the class file, other languages target the JVM too: Kotlin, Scala and Clojure all produce class files that run alongside Java's.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.