Translators, Compilers, Interpreters, and Bytecode in Java
In this lesson we cover four key concepts that explain how your code becomes a running program: translator, compiler, interpreter, and bytecode. Let's start with the translator.
What is a translator?
A translator is a program that converts code written in one language into another. Most often, source code is translated into machine code that the processor can run. Translators are broadly divided into two types: compilers and interpreters.
What is a compiler?
A compiler takes the entire source code, checks it for errors, and — if there are none — converts it completely into machine code. The resulting program is then executed by the processor. This makes execution fast and means no compiler is needed on the user's machine. The trade-off: the program becomes tied to a specific operating system and processor architecture, and any change to the code requires recompilation.
Compiler process:

Advantages:
- fast program execution;
- no compiler needed on the end user's system.
Disadvantages:
- the program depends on the OS and processor it was compiled for;
- code changes require recompilation.
What is an interpreter?
An interpreter reads the source code and executes it line by line, as it reads. This gives flexibility: the code isn't tied to a specific operating system and ports easily between platforms, and no recompilation is needed after changes. The price for that flexibility is usually slower execution, since the code is parsed again on every run.
Interpreter process:

Advantages:
- independence from the operating system;
- no recompilation required after code changes.
Disadvantages:
- slower execution;
- an interpreter is required to run the program.
What is bytecode in Java?
Java uses a third approach that combines the advantages of a compiler and an interpreter — bytecode.

The process starts with Java source code in a .java file. This code passes through the compiler (javac), which checks it for errors and converts it not into the machine code of a specific processor, but into bytecode — an intermediate, platform-independent representation. This produces a .class file.
Bytecode isn't tied to any specific platform: it can run on any device that has a Java Virtual Machine (JVM) installed. The JVM is what runs the bytecode on a particular system.
A modern JVM doesn't just interpret bytecode. It combines interpretation with JIT (Just-In-Time) compilation: the most frequently executed ("hot") sections of bytecode are compiled into native machine code while the program runs. Thanks to this, Java gets both the portability of bytecode and performance close to that of compiled languages.
Important
Because of bytecode, Java is often called an "interpreted language," but that's inaccurate. A modern JVM (such as HotSpot) combines interpretation with JIT compilation into native code, and in some scenarios ahead-of-time (AOT) compilation is used as well (GraalVM).
Comparison of the approaches
| Approach | How it processes code | Speed | Portability |
|---|---|---|---|
| Compiler | Converts the whole code to machine code in advance | High | Tied to the OS and processor |
| Interpreter | Executes the code line by line at runtime | Low | OS-independent |
| Bytecode (Java) | Compiled to .class, then the JVM interprets and JIT-compiles it | High (thanks to JIT) | Runs on any JVM |
Frequently asked questions
What's the difference between a compiler and an interpreter?
A compiler converts the entire source code into machine code before execution, while an interpreter reads and executes the code line by line at runtime. Compilation gives speed; interpretation gives flexibility and platform independence.
What is bytecode in Java?
Bytecode is an intermediate, platform-independent representation of a program, produced by the javac compiler from a .java file. It is stored in .class files and executed by the Java Virtual Machine (JVM).
Is Java a compiled or interpreted language?
Both. The source code is compiled into bytecode, and the JVM then executes it using a mix of interpretation and JIT compilation into native machine code. That's why calling Java "purely interpreted" is inaccurate.
What is JIT compilation?
JIT (Just-In-Time) is the compilation of "hot" sections of bytecode into native machine code while the program runs. It lets Java combine the portability of bytecode with high performance.
Why does Java use bytecode instead of machine code directly?
For portability: the same bytecode runs on any platform with a JVM installed, without recompiling for each processor and operating system.
Video Explanation
Prefer video format? Watch this lesson with examples and explanations.
Comments