The labs on this site need JavaScript to run. The same content is written out below.
Fundamentals › Java
How does Java code run?
The Hello.java file that we write is text for people to read. When you run it with java Hello, this text is not run as it is, but goes through two steps. When you use the command javac Hello.java in a terminal (a window where you type commands as text), a program called javac (the compiler) reads this text and turns it into a file named Hello.class. This job is called compiling. Hello.class contains bytecode, which the JVM reads. Next, when you use the command java Hello, the JVM (Java Virtual Machine) starts, reads Hello.class, and runs main. In this lab you remove the javac line, make the source text wrong, or edit it after compiling, and the real javac and java commands are run, to show whether Hello.class is created and what java Hello runs.
Checked against real execution · Ran the javac and java commands of JDK 21 for real in 6 combinations and checked the results against them
# Hello.java
public class Hello {
// main: the method that the java command calls first
public static void main(String[] args) {
System.out.println("Hi");
}
}
# Terminal
# Compile: javac reads Hello.java and creates Hello.class
javac Hello.java
# Run: java starts the JVM, which runs main in Hello.class
java Hello
The compiler and runtime are JDK 21.0.12.1 (javac 21, java 21). All 6 combinations were checked against real runs: for each combination, the same text as the code on the screen (the # Hello.java section and the # Terminal section) was written in an empty folder, the source file and the commands were read from that text, and the real javac program and java program were started as processes and run. What was checked is whether Hello.class appeared in the folder, the exit code and standard output of javac, the first error message and the number of errors and the line of the error, the exit code, output, and error message of java, whether the edit leaves Hello.class unchanged, and the first four bytes of the Hello.class file (CAFEBABE) and its version (65, Java 21). That the "Bye" is printed when you use the javac command again after the edit was also checked by a separate run. The commands that were run differ from the screen in two ways. To read the output text and the error messages in the same way, options were added to javac and java that set the output encoding to UTF-8 and the message language to English (-Dstdout.encoding=UTF-8, -Duser.language=en, and so on). Without the options, on the PC used to write this lab (Korean Windows), the java Hello command gives the same error as a Korean message. I opened the documentation and checked it. I followed section 1.2 of the Java Virtual Machine Specification, Java SE 21 Edition (the JVM does not know the Java language and knows only the class file format, and a class file contains bytecode, which are JVM instructions), section 4.1 of the same specification (the magic value at the very beginning of a class file is 0xCAFEBABE, and the major version for Java SE 21 is 65; I read only part of this chapter), the JDK 21 documentation of the javac tool (it reads .java source files and compiles them into .class files, creates them in the same folder as the source if nothing else is set, and puts the class files in the output folder if there are no errors), and the documentation of the java tool (it starts a JVM, loads the specified class, and calls main, and if the class path is not set it is the current folder; I read only the first part and could not read the exit code section). That no Hello.class is created when there is an error, that the exit codes are 0 and 1, and the text of the error messages are not set by the documentation but were observed on this JDK. The code on the screen was cut down to the situation where the folder has only one file, Hello.java, and classes with a package, class path settings, jar files, and an IDE or build tool compiling for you are not covered. The way of running a source file directly, as in java Hello.java (source-file mode), is not used on the screen either. When I ran it on this JDK, it printed Hi without creating Hello.class (the java documentation also explains that it compiles the source in memory and runs it), and a source with a missing semicolon failed with the same compile error in this mode too. I also confirmed that if, after a successful compile, you change the source to something wrong and use the javac command again, you get an error but the old Hello.class stays in the folder and the java Hello command runs the old code, but the screen does not cover this. How the JVM loads Hello.class is covered in the in-depth lab "Class loading and initialization", and JIT, which recompiles bytecode into machine code, is covered in the in-depth lab "JIT warmup".
Previous lab: Thread pools · Next lab: File I/O
Struck-through text was removed from the first version of the code; highlighted text was added.