Java compiler

What is a Java compiler?

A Java compiler is a program that takes the text file work of a developer and compiles it into a platform-independent Java file. Java compilers include the Java Programming Language Compiler (javac), the GNU Compiler for Java (GCJ), the Eclipse Compiler for Java (ECJ), and Jikes.

Programmers typically write language statements in a given programming language one line at a time using a code editor or an integrated development environment (IDE). The resulting file contains what are called the source statements. The programmer then runs a compiler for the appropriate language, specifying the name of the file that contains the source statements.

Java and Java programmers are no exception. The Java compiler accepts high-level Java source code and converts it into bytecode that can be understood by a Java Virtual Machine (JVM) in order to produce the desired results.

At run time, the compiler parses (analyzes) all the language statements syntactically and then, in one or more successive stages or "passes," builds the output code, making sure that statements referring to other statements are referred to correctly in the final code.

Generally, Java compilers are run and pointed to a programmer's code in a text file to produce a class file for use by the JVM on different platforms. Jikes, for example, is an open source compiler that works in this way, and so does the primary compiler included in the Java Development Kit (JDK) called javac. This compiler, which is written in Java, reads class and interface definitions written in Java and like Jikes, converts them into bytecode class files.

To run the Java compiler, the programmer must run the Javac.exe command from the command prompt. The compiler, like Java is platform-independent, meaning it can compile code and then run it on any operating system (OS). However, it is language-specific, so it cannot be used to compile and convert source code written in other languages, like Python, C++, etc.

Typical steps performed by compilers diagram
The typical compiler steps include lexical analysis, syntax analysis, IR code generation, optimization, and output code generation.

What is the purpose of a Java compiler?

The main purpose of a Java compiler (or a compiler in any programming language) is to translate the high-level Java source code into a machine code file consisting of machine-readable 0s and 1s, and then execute the file.

Compilation is essential because the machine cannot understand a human-readable language like Java. By translating human-readable code into machine-readable language, the Java compiler ensures that the code runs and produces the expected output.

A Java compiler also functions as Java's error detection mechanism. Once it is activated, it checks for syntax errors and generates a list of all detected errors. It does not generate object code unless the programmer rectifies the errors. The compiler can also add additional code to the program if required.

Java compiler and bytecode

After compiling the source code (a .java file), the compiler generates intermediate object code called bytecode which is a .class file. Bytecode is not the same as machine code. Rather, it is a binary code that can be understood and interpreted by a JVM on the underlying OS. Because the bytecode consists of a series of 0s and 1s, it is not human-readable or human-understandable. To produce bytecode, the compiler might require additional memory.

How the Java compiler works

The programmer writes Java source code and then runs a compiler like javac. The compiler checks whether the source file is available and generates java bytecode (.class file). If the source file is not found, it generates an error message. If the source file is available and the bytecode file is generated (which happens regardless of OS and processor architecture), the bytecode file gets saved automatically on the disk. The JVM ​interprets and executes the class file at runtime on the underlying OS.

If the compiler finds errors, it generates a list of error messages. The programmer fixes the errors and runs the compiler again to recompile the program. This step is important to generate the corrected machine-readable object code. If the compiler doesn't find any errors, it generates the required object code.

Java compiler options

The javac compiler provides numerous standard options for programmers. These include the following:

  • -version. It displays information about the compiler.
  • -help. It prints a summary of standard options.
  • -nowarn. It turns off warnings.
  • -g. It generates debugging information (line number, source file information, local variables).
  • -verbose. It generates "verbose" output, including information about compiled source files and loaded classes.
  • -d directory. It allows the programmer to set the destination directory (which must already exist) for compiled class files.
  • -deprecation. It identifies retired APIs.

All the above options are case-sensitive.

What is a just-in-time compiler?

A just-in-time (JIT) compiler comes with the Java VM. Its use is optional, and it is run on the platform-independent code. The JIT compiler then translates the code into the machine code for different hardware so that it is optimized for different architectures. Once the code has been (re-) compiled by the JIT compiler, it will usually run more quickly than the Java code that can only be executed one instruction at a time.

How the JVM works diagram
The Java virtual machine interprets bytecode and converts it to machine language that is platform-specific, i.e., Windows, Linux, etc.

Java compiler vs. Java interpreter

Java programmers use a Java compiler and an interpreter. They are both essential in high-level languages like Java and both play a role converting high-level code to low-level machine code. However, they work differently. A compiler scans the complete source code in one go and combines all the code files into one executable program (.exe file). It then executes the entire file and checks the code for syntax and other errors. If errors are detected, it will display all error and warning messages.

Once the errors are fixed, the compiler can be run again to confirm fixes and verify code quality. If the compiler doesn't find any errors, it will convert the source code to machine code and produce the required results.

An interpreter on the other hand, executes the programming statements in the source code line by line. If it detects an error, it highlights it and halts further execution. Only when the error is corrected will it restart executing the code. Simply put, the interpreter displays one error at a time and waits for each error to be corrected before it continues execution, while a compiler shows all errors at the same time and continues executing until it reaches the end of the source code file.

Another difference is that the compiler takes longer to analyze the source code. Debugging errors also slower. And the program executes only after all errors are fixed and it has been entirely compiled. In contrast, an interpreter takes less time to analyze the code. Code debugging is also faster, and program execution happens line by line.

Learn how to fix the top 10 most common compile time errors in Java and read about checked versus unchecked exceptions in Java.

This was last updated in January 2024

Continue Reading About Java compiler

Dig Deeper on Development tools for continuous software delivery

App Architecture
Software Quality
Cloud Computing