Appearance
How Java Works: JVM, JRE, JDK, and Writing Your First Program
What Java Actually Is
Before you write a single line of code, you need to understand what Java is at its core. Java is a platform independent, object oriented programming language. You have already seen what object oriented means: inheritance, polymorphism, encapsulation, and abstraction. But the platform independent part is the big deal, and understanding it will change how you think about every Java program you ever write.
Most languages compile your code into machine code that runs on one specific operating system and one specific chip architecture. Write a C program on Windows and compile it: you get a Windows executable. Take that same binary to a Mac and it will not run. You need to recompile it for Mac, and possibly change the code too. Every target platform is a new job.
Java solved this problem in a fundamentally different way, and that solution is the story of how Java runs.
The Journey from Source Code to Running Program
Imagine you write a Java file called Student.java. What happens between you saving that file and a program actually running on your machine? There are two completely separate stages, and most beginners blur them together.
Stage One: Compilation
You run a command called javac (Java Compiler):
javac Student.javaThe Java compiler reads your .java source file and produces a new file: Student.class. This .class file does not contain machine code. It contains something called bytecode.
Bytecode is not instructions for your Intel chip, or your Apple M1, or your ARM processor. Bytecode is instructions for a machine that does not physically exist: the Java Virtual Machine (JVM). The JVM is an imaginary, universal computer. Because it is imaginary and you get to define what its instruction set looks like, you can make the same bytecode mean the same thing everywhere.
So after stage one, you have a Student.class file sitting on disk. This file is platform independent. You can copy it to any computer on the planet and it carries its meaning with it.
Stage Two: Execution
Now you run:
java StudentThis launches the JVM on your specific machine. The JVM reads Student.class and begins executing it. Here is the key: every operating system has its own JVM. Windows has a Windows JVM. macOS has a macOS JVM. Linux has a Linux JVM. Each of those JVMs is platform dependent, meaning it knows how to talk to its specific operating system and chip.
But all of them read the same bytecode. The same Student.class file that compiled on your Windows laptop runs on your friend's Mac without any changes. Write once, run anywhere. This is not a marketing slogan. It is a precise technical description of a two stage translation process.
The interview question you will definitely face: "Why is Java platform independent?"
The answer is: Java compiles not to machine code but to bytecode. Bytecode is instructions for the JVM, which is a virtual machine. Every real operating system has its own JVM installed. Every JVM on every OS reads the exact same bytecode. So you compile once, and the bytecode runs on any machine that has a JVM. Only the JVM itself is platform dependent, not your Java program.
What the JVM Actually Does
The JVM is an abstract machine: it does not exist as hardware, it is software that behaves like a computer. Its input is bytecode and its output is machine code for the CPU it is running on.
The part that does this conversion is the JIT compiler (Just In Time compiler). It takes bytecode and turns it into native machine code at runtime, so the CPU can execute it.
A Trap Every Beginner Falls Into
You edit Student.java and save it. Then you run java Student. The output looks wrong. You make more changes, run again. Still wrong.
The trap: you forgot to recompile. The JVM reads only .class files. It never touches your .java source file. If you edit the source and run java Student without first running javac, you are executing the old bytecode from the last time you compiled.
Always run both steps:
javac Student.java
java StudentOr chain them in one terminal command so you cannot forget:
javac Student.java && java StudentThis is not an edge case. It is one of the most common sources of confusion for people who are new to Java.
JVM, JRE, and JDK: The Russian Dolls
These three acronyms appear on every Java interview, every job description, and every installation page. Most beginners treat them as vague synonyms. They are not. They are nested containers, like Russian dolls, where each outer doll contains everything inside it.
Think of it this way. You have the smallest doll first. Then a larger one that contains the small one. Then the largest one that contains both.
The JVM (Java Virtual Machine)
The JVM is the innermost doll. It is the execution engine. Its job is to take bytecode and run it, using its JIT compiler to produce machine code.
You cannot have only the JVM. It always comes as part of the JRE.
The JVM is platform dependent. A Windows JVM is different from a Linux JVM because each one knows how to talk to its own operating system. Your bytecode is the same; the JVM adapts it to where it runs.
The JRE (Java Runtime Environment)
The JRE is the middle doll. It contains the JVM plus a large set of class libraries. These are the standard Java APIs: java.lang, java.util, java.io, and many others. When your bytecode calls Math.abs() or Arrays.sort(), those implementations come from the class libraries in the JRE. The JVM needs these libraries at runtime to complete execution.
If you have only the JRE: you can run any compiled Java program. You cannot write new Java code or compile it.
The JDK (Java Development Kit)
The JDK is the outermost doll. It contains the entire JRE, plus the development tools you need to write Java programs. The most important tool in the JDK is javac, the Java compiler. It also includes a debugger and other development tools.
If you have the JDK: you can both write Java code and run it. As a developer, the JDK is what you install.
Here is how to remember the distinction: a user who just runs your application needs the JRE. You, the developer who writes and compiles the application, need the JDK.
The interview question: "What is the difference between JVM, JRE, and JDK?"
JVM executes bytecode. JRE is JVM plus the standard class libraries needed at runtime. JDK is JRE plus the compiler and development tools. Every outer container includes everything inside it.
All three are platform dependent: you download the JDK built for your operating system. Only your compiled bytecode is platform independent.
Installing the JDK
Download the JDK for your operating system from Oracle's official Java downloads page (installing the JDK gives you the JRE and JVM too). Then check the installation in a terminal:
java -versionIt prints the installed Java version.
Java Editions: JSE, JEE, and JME
When you download Java, you might see references to JSE, JEE, and JME. These are not different languages. They are different sets of APIs built on top of core Java.
JSE stands for Java Standard Edition. This is the core language: all the fundamentals, the standard library, everything you are learning in this course. When people say "Java," they usually mean JSE.
JEE stands for Java Enterprise Edition, now called Jakarta EE. This includes JSE plus additional APIs for large scale enterprise applications: servlets, transactions, JPA for database access, and APIs used in big ecommerce systems and web applications built for companies.
JME stands for Java Micro Edition. This is a trimmed down set of APIs designed for resource constrained devices like mobile phones and embedded systems. It has less memory and processing power available, so the API set is smaller.
You are learning JSE. Everything else is built on top of it.
Your First Java Program
Now you understand the machinery. Time to write actual code. The canonical first program:
java
// File must be saved as: Employee.java
public class Employee {
// The JVM looks for this exact method signature to start the program
public static void main(String[] args) {
int a = 10; // declare an integer variable named a, assign it the value 10
System.out.println("output of a is " + a); // print the value to the console
}
}Save this file as Employee.java. The filename must match the public class name exactly, including capitalization. This is not a style preference. The compiler (javac) enforces it, not the JVM: the Java Language Specification (§7.6) lets file-based compilers reject a public class that is not in a file of the same name, and javac does. If your class is named Employee and your file is named employee.java or Employee2.java, the compiler will refuse with an error.
Now compile and run:
javac Employee.java
java EmployeeYou will see printed to the console:
output of a is 10The first line of output is the result of the System.out.println call. System is a class in the Java standard library. out is a static field on System that represents the standard output stream connected to your terminal. println is a method on that stream that prints the text you give it and then moves to a new line.
The + operator between "output of a is " and a concatenates the string with the value of a. Java automatically converts the integer a to its string representation for concatenation.
Comments in Java
Java has two comment styles. Both appear in real code constantly.
Single line comments start with // and run to the end of the line. The compiler ignores everything after // on that line.
java
// This entire line is a comment
int x = 5; // This part is code; this part after the slashes is a commentMulti line comments start with /* and end with */. Everything between those markers is ignored by the compiler, and they can span as many lines as you need.
java
/* This is a multi line comment.
You can write as many lines as you want here.
The compiler skips all of it. */Comments do not affect compilation or execution at all. They exist purely for humans reading the code.
Dissecting public static void main(String[] args)
main is the starting point of every Java program. The JVM calls main, and from there your code calls other methods and classes.
java
public static void main(String[] args)public means the method can be called from anywhere. The JVM calls main from outside your class and package, so it must be accessible.
static means the method belongs to the class, not to an object. Normally you need an object to call a method (obj.method1()). A static method can be called with the class name (Employee.main(args)), so the JVM can start your program without first creating an object.
void is the return type: main returns nothing.
main is the name the JVM looks for.
String[] args receives command line arguments passed when the program is started.
(Since JDK 25 the launcher also accepts a simpler void main() without public, static, or args. The full form above remains the standard one.)
What a Class Can Contain
A Java class is a container that holds four kinds of things. Each of these is a topic that goes deep, and you will explore each one in detail in future articles. For now, you need to know they all exist inside a class.
Variables hold data. A class can have static variables that belong to the class itself, and instance variables that belong to individual objects created from the class.
Methods define behavior. They are functions inside the class. main is a method.
Constructors are special methods that run when you create a new object. They set up the initial state of the object.
Nested classes are classes defined inside other classes. Java allows this for organizing tightly related code.
Understanding that a class is a structured container for all of these things is the right mental model. A class is not just a collection of code: it is a description of a type of object, with data (variables), behavior (methods), and a creation process (constructors).
The Full Pipeline in One Picture
The JRE wraps the JVM and adds the class libraries your code needs at runtime. The JDK wraps the JRE and adds javac and the other tools you need to write and compile code. As a developer, you install the JDK.
Check yourself
- Why is a Java program platform independent while the JVM itself is platform dependent?
- What is the difference between the JVM, the JRE, and the JDK?
- You edit
Student.javaand runjava Student. Your change does not show up. Why? - What does the JIT compiler do?
- Why is
mainpublicandstatic? - What are JSE, JEE, and JME?
Answers
javaccompiles to bytecode, which is instructions for the JVM, not for a real CPU. Each operating system has its own JVM that understands the same bytecode.- JVM executes bytecode. JRE = JVM + class libraries (enough to run programs). JDK = JRE + compiler, debugger and other development tools.
- The JVM runs the old
Student.class. Recompile withjavacfirst. - It converts bytecode into machine code for the current CPU at runtime.
publicso the JVM can call it from outside the class;staticso it can be called without creating an object first.- Standard Edition (core Java), Enterprise Edition (JSE + enterprise APIs such as transactions, servlets and persistence; now called Jakarta EE), and Micro Edition (APIs for resource-constrained devices such as mobiles).