Java Bytecode
Definition
Bytecode is the compact, platform-independent instruction set that the JVM executes. The javac compiler does not turn Java source into native machine code; it produces bytecode stored in .class files. Each instruction, such as iload, iadd, or invokevirtual, is a small operation for the JVM’s stack-based machine. Because the bytecode is identical on every platform, only the JVM needs to be ported, which is how Java delivers Write Once, Run Anywhere.
Key Takeaways
- Bytecode is an intermediate format between source code and native machine code. It targets the JVM, not your CPU.
- It is the same across platforms, so a compiled
.classor JAR runs unchanged on Windows, Linux, and macOS. - The JVM is a stack-based machine, so bytecode pushes and pops values on an operand stack instead of naming CPU registers.
- You can read the bytecode of any class with
javap -cto see exactly what the compiler produced.
How It Works
javaccompiles each.javafile into one or more.classfiles containing bytecode and a constant pool.- The JVM verifies the bytecode is safe before running it, rejecting malformed code with a VerifyError.
- The interpreter executes bytecode instruction by instruction using the operand stack.
- Frequently executed bytecode is handed to the JIT compiler and turned into native machine code.
Where It Is Used
- Kotlin, Scala, Groovy, and Clojure all compile to the same JVM bytecode and interoperate with Java.
- Frameworks like Spring and Hibernate generate or manipulate bytecode at runtime for proxies and instrumentation.
- Tools such as ASM and ByteBuddy let libraries create and rewrite bytecode programmatically.