How a Java program runs
The command java Main.java checks a program and runs it right away. Inside, it takes two steps. In this lesson we take them apart and see how Java gets from the program's text to a line in the output.
First, the problem these two steps solve. A processor understands only machine code, a set of commands that differs from one kind of processor to another. A program translated into machine code for one computer may not start on another: that one has a different processor or a different operating system.
Remember the orchestra. A composer writes the score once, and orchestras in different cities play it. Java works the same way: the program is translated once and runs on any computer.
public class Main {
public static void main(String[] args) {
System.out.println("Run anywhere"); // Run anywhere
}
}Save this program to a file named Main.java and type two commands in the terminal, one after the other:
$ javac Main.java
$ java Main
Run anywhereLet's see what each one does.
Step 1: javac writes bytecode
javac is the Java compiler. It checks the text and translates it into bytecode: instructions not for the processor but for a special program, the JVM. It puts the result next to the source, in the file Main.class. javac does not run the program.
Bytecode is the score from the first lesson, written out as a clean copy: it is written once, and it fits any computer. You can look inside it with the command javap -c Main. The method main of our program holds four instructions:
getstaticfetchesSystem.out;ldcloads the string"Run anywhere";invokevirtualcallsprintln;returnends the method.
Step 2: the JVM runs bytecode
The command java Main starts the JVM, the Java virtual machine. It is a program that reads the bytecode from Main.class and runs it, translating the instructions into commands for this computer's processor. Note that the command takes the class name Main, not the file name.
Each operating system has its own JVM: one for Windows, one for macOS, one for Linux. The bytecode is the same for all of them. Hence Java's motto: "write once, run anywhere". A Main.class compiled on Windows runs on Linux without recompiling.
Interviewers like to ask this: why does Java not depend on the platform, the operating system and the processor? The answer has two halves: the bytecode is portable, and every platform has its own JVM.
This is where the orchestra picture falls short. Each orchestra plays a piece a little differently, while the JVM runs bytecode the same way on every computer: the program prints the same text.
JDK, JRE and JVM
Another classic interview question is how these three abbreviations differ. They nest inside one another:
- the JVM runs bytecode;
- the JRE is the JVM plus the standard library, ready-made code such as
System.out.println; that is enough to run programs; - the JDK is the JRE plus developer tools: the compiler
javac, the programjavapand the packerjar, which bundles.classfiles into one archive.
You can write programs only with the JDK: it is the only one that has javac.
Two steps in one command
The command java Main.java takes both steps on its own: it compiles the program in memory and runs it right away. No Main.class file appears. Inside, it calls the compiler too, so it also needs the JDK.
For a program in one file, this is handy. You need javac when the bytecode must be saved, to run it later or on other computers.
Common mistake
The class was run by its file name, .class included:
$ java Main.class
Error: Could not find or load main class Main.classThe command java expects a class name and finds the file Main.class for it on its own. Given Main.class, it looks for a class with that odd name and finds none. The right command is java Main, without the extension.
Key points
javac Main.javatranslates the program into bytecode and saves it inMain.class; it does not run the program.java Mainstarts the JVM, which runs the bytecode; each platform has its own JVM, while the bytecode is the same for all.- The JVM runs bytecode, the JRE adds the standard library to it, and the JDK adds
javacand other tools on top. java Main.javacompiles the program in memory and runs it right away, without creatingMain.class.