Java is a widely-used, platform-independent programming language. Now that we know about JDK, JRE, and JVM. These are the foundation of Java development and execution. Let’s break down each component and walk through the end-to-end process of running a Java program.
How a Java Program Works
Writing the Code
A Java program starts with writing the code in a file with a .java
extension. This code consists of classes and methods, which are the building blocks of a Java program.
1 2 3 4 5 |
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } |
This program simply prints “Hello, World!” to the console.
Compiling the Code
Once the code is written, it must be compiled into a format the computer can understand. This is where the Java Compiler (provided by the JDK) comes in.
To compile the code, open a terminal (or command prompt) and use the following command:
1 |
javac HelloWorld.java |
javac
: This is the Java compiler that converts your human-readable.java
file into bytecode. Bytecode is a low-level, platform-independent code that the JVM can execute.- After running the command, a new file called
HelloWorld.class
will be generated. This file contains the bytecode.
Running the Program
Now, it’s time to run the compiled bytecode. Java Runtime Environment (JRE), provides the necessary tools, including the JVM, to run the bytecode.
To run the program, use the following command:
1 |
java HelloWorld |
Here’s what happens behind the scenes when you run this command:
- The JRE starts up and looks for the
HelloWorld.class
file. - The JVM in the JRE is responsible for executing the bytecode. The JVM is platform-independent, meaning it ensures that the bytecode can run on any operating system (like Windows, macOS, or Linux) without modification.
JVM Execution
The JVM handles several important tasks while running a Java program:
- Class Loading: When you execute the Java program, the JVM loads the bytecode from the
.class
file into memory. This is called the class loading phase. The JVM uses a class loader to load the bytecode dynamically at runtime. - Bytecode Verification: The JVM verifies the bytecode to ensure it adheres to Java’s security rules. This process ensures that the bytecode does not contain illegal operations that could harm the system or violate security policies.
- Execution: The JVM uses either an interpreter or a Just-In-Time (JIT) compiler to convert the bytecode into machine code (the code that the computer understands). The interpreter translates bytecode line by line, while the JIT compiler translates entire sections of bytecode into machine code for faster execution.
- Memory Management: The JVM is responsible for managing memory. It allocates memory for objects and variables and takes care of garbage collection — automatically cleaning up memory used by objects that are no longer in use.
Output
As the program runs, the JVM executes the bytecode and produces output. In the case of the HelloWorld
example, it prints:
1 |
Hello, World! |
This output is shown in the console.