What Class Version Numbers Tell the JVM During Class Loading
Why your code fails before it even runs
When a Java program runs, what you see is the application starting up, loading classes, and executing logic. But deep in the background, the JVM is doing a lot of compatibility checks before anything actually runs. One of the first things it looks at in every .class
file is a version number embedded in the file itself. This version tells the JVM which Java version was used to compile the file. If that version is too new for the JVM that’s running the code, you won’t get far. You’ll hit an immediate error and the class won’t be loaded at all.
How Class Versioning Works in the JVM
As a .class
file lands in the hands of the JVM, the very first thing it does is peek at the file’s opening bytes. Before it runs anything or links anything, the JVM checks a few fixed markers that tell it what kind of file it’s dealing with and whether it can use it at all. These early checks are about structure and compatibility, not behavior. The version number baked into the class file gives the JVM a hard rule to follow: don’t run code you don’t understand.
The Structure of a Class File
Every Java class file starts with a header. The very first four bytes are a fixed magic number: 0xCAFEBABE
. This isn’t decorative. It’s how the JVM can quickly confirm it’s reading a Java class and not some random binary blob. Right after that comes the version info, which is split into two parts: minor and major version numbers. Both are stored as unsigned 16-bit integers.
The minor version almost always sits at zero. The major version is the one that matters. It tells the JVM what version of the compiler was used to build this file, and by extension, what features or bytecode instructions might be in use. Here are a few examples: Java 8 class files use version 52, Java 11 uses 55, and Java 21 uses 65. These numbers aren’t written in decimal in the file, but that’s what they translate to when the JVM reads them.
So the version header for a Java 17 class file would show major version 61. That tells the JVM this file might be using newer bytecode instructions or metadata that older runtimes wouldn’t know how to handle.
You can confirm the version of a class file using javap -verbose
:
Keep reading with a 7-day free trial
Subscribe to Alexander Obregon's Substack to keep reading this post and get 7 days of free access to the full post archives.