Java Two-step execution process:
Java is a platform-independent language that follows a two-step execution process:
Compilation (source code -> bytecode)
Execution (bytecode -> machine code via JVM)
Compilation in Java
Java source code (.java files) is compiled by the Java Compiler (javac) into Bytecode, stored in .class files. This bytecode is platform-independent and ready to run on any system with a JVM.
Internally, compilation involves:
Parsing: Converts code into syntax trees (AST).
The compiler reads your source code (
.javafile`) and checks the syntax.It then converts the code into a tree-like structure called an Abstract Syntax Tree (AST).
This tree represents the logical structure of your program — classes, methods, variables, etc.
Example: The statement
int x = 10;becomes a small tree node, a variable declaration with typeintand value10.
Entering: Populates symbol tables.
The compiler records class and member names (like variables, methods, etc.) into a symbol table.
Think of it as the compiler’s dictionary — it stores information about what exists and where it is defined.
Example: It remembers that there’s a class
HelloWorldwith amainmethod.
Annotation Processing: Handles annotations.
If your code has annotations (like
@Override,@Deprecated,@Entity, etc.), this phase processes them.Tools or frameworks can even generate new code or files during this stage.
Example:
@Entityin frameworks like Hibernate gets processed here.
Attribution: Performs type checking and name resolution.
The compiler now checks types — ensuring variables, return types, and method calls are valid.
It also resolves names — linking each variable or method call to its actual declaration.
Example: Checks that
xis declared before use and thatSystem.out.println()exists.
Flow Analysis: Checks for variable use and reachability.
Here, the compiler performs logical checks:
Are all variables initialized before use?
Is there unreachable code (like code after
return)?
It ensures your code’s flow makes sense and follows Java rules.
Desugaring: Removes syntactic shortcuts.
Java allows shortcuts (syntactic sugar) — for example:
for (int i : list)→ becomes a normal iterator-based loop internally.var→ becomes the actual inferred type.
In this stage, the compiler rewrites these shortcuts into simpler, more explicit Java constructs.
Generation: Produces .class files.
Finally, the compiler translates the checked and simplified AST into bytecode.
The bytecode is stored in
.classfiles — this is what the JVM actually runs.So
HelloWorld.java→HelloWorld.class.
Execution via JVM
The .class files are executed by the Java Virtual Machine (JVM), which includes the following stages:
Class Loader
Loads the main class and other dependencies into memory.
Primordial Loader: Default system loader.
Non-primordial Loader: Custom loaders for advanced control.
Class r = loadClass(String className, boolean resolveIt);
Bytecode Verifier
Checks that the loaded bytecode is safe to execute. It ensures:
Variables are initialized
Method signatures are correct
Private access rules aren’t violated
No stack overflows
Just-In-Time (JIT) Compiler
Converts bytecode into native machine code at runtime for faster execution.