Java implementations typically use a two-step compilation process. Java source code is compiled down to bytecode by the Java compiler. The bytecode is executed by a Java Virtual Machine (JVM). Modern JVMs use a technique called Just-in-Time (JIT) compilation to compile the bytecode to native instructions understood by hardware CPU on the fly at runtime.

Some implementations of JVM may choose to interpret the bytecode instead of JIT compiling it to machine code, and running it directly. While this is still considered an "interpreter," It's quite different from interpreters that read and execute the high level source code (i.e. in this case, Java source code is not interpreted directly, the bytecode, output of Java compiler, is.)

It is technically possible to compile Java down to native code ahead-of-time and run the resulting binary. It is also possible to interpret the Java code directly.

To summarize, depending on the execution environment, bytecode can be:

  • compiled ahead of time and executed as native code (similar to most C++ compilers)
  • compiled just-in-time and executed
  • interpreted
  • directly executed by a supported processor (bytecode is the native instruction set of some CPUs)
Answer from Mehrdad Afshari on Stack Overflow
🌐
Reddit
reddit.com › r/learnprogramming › why is java generally considered compiled and python interpreted when they both have essentially the same process?
Why is Java generally considered compiled and Python interpreted when they both have essentially the same process? : r/learnprogramming
June 26, 2023 - So, it may compile, then interpret, but it lacks an object file. Java has a .class file. Python only has the original source code. I think there are ways to create something that could be compiled in Python, but as normally taught, you never have an object code, so the compiled result is not saved anywhere.
Top answer
1 of 9
292

Java implementations typically use a two-step compilation process. Java source code is compiled down to bytecode by the Java compiler. The bytecode is executed by a Java Virtual Machine (JVM). Modern JVMs use a technique called Just-in-Time (JIT) compilation to compile the bytecode to native instructions understood by hardware CPU on the fly at runtime.

Some implementations of JVM may choose to interpret the bytecode instead of JIT compiling it to machine code, and running it directly. While this is still considered an "interpreter," It's quite different from interpreters that read and execute the high level source code (i.e. in this case, Java source code is not interpreted directly, the bytecode, output of Java compiler, is.)

It is technically possible to compile Java down to native code ahead-of-time and run the resulting binary. It is also possible to interpret the Java code directly.

To summarize, depending on the execution environment, bytecode can be:

  • compiled ahead of time and executed as native code (similar to most C++ compilers)
  • compiled just-in-time and executed
  • interpreted
  • directly executed by a supported processor (bytecode is the native instruction set of some CPUs)
2 of 9
137

Code written in Java is:

  • First compiled to bytecode by a program called javac as shown in the left section of the image above;
  • Then, as shown in the right section of the above image, another program called java starts the Java runtime environment and it may compile and/or interpret the bytecode by using the Java Interpreter/JIT Compiler.

When does java interpret the bytecode and when does it compile it? The application code is initially interpreted, but the JVM monitors which sequences of bytecode are frequently executed and translates them to machine code for direct execution on the hardware. For bytecode which is executed only a few times, this saves the compilation time and reduces the initial latency; for frequently executed bytecode, JIT compilation is used to run at high speed, after an initial phase of slow interpretation. Additionally, since a program spends most time executing a minority of its code, the reduced compilation time is significant. Finally, during the initial code interpretation, execution statistics can be collected before compilation, which helps to perform better optimization.

Discussions

Definitions of “interpreted language” and “compiled language” with explanations of why Python and Java are or are not such languages - Python in Education - Discussions on Python.org
i’m not sure whether this belongs in the education category or a more general category. i’m dissatisfied with the definitions of “interpreted language” and “compiled language” that i have seen. as an educator, i need to explain these concepts to students. many people classify the ... More on discuss.python.org
🌐 discuss.python.org
2
September 6, 2024
gcc - Java is interpreted on runtime? - Stack Overflow
Java compiler compiles to binary like gcc compiles C code ? or it just compile to another type of "language" that will be interpreted by another thing? I can't run it. It must be , I gues... More on stackoverflow.com
🌐 stackoverflow.com
What is Java (compiler lang / or interpreter lang) - Oracle Forums
Hi, at our company we have a deadly war going on, please help us :) Some programmers, including me, saying that Java is a interpreter language, because the bytecode cant run on a processor, because ... More on forums.oracle.com
🌐 forums.oracle.com
August 6, 2001
Java is called an interpreted language, yet Java is a compiled language that produces a binary output stream. Explain how this language can be both compiled and interpreted.
Solution For Java is called an interpreted language, yet Java is a compiled language that produces a binary output stream. Explain how this language c More on askfilo.com
🌐 askfilo.com
1
November 4, 2025
🌐
GeeksforGeeks
geeksforgeeks.org › java › why-java-is-called-a-compiler-interpreter-language
Why Java is Called a Compiler Interpreter Language? - GeeksforGeeks
January 22, 2026 - Java is known as a compiler-interpreter language because it uses both compilation and interpretation to execute a program.
🌐
Python.org
discuss.python.org › python in education
Definitions of “interpreted language” and “compiled language” with explanations of why Python and Java are or are not such languages - Python in Education - Discussions on Python.org
September 6, 2024 - i’m not sure whether this belongs ... python and java differently for these two terms. often java is classed as compiled but not interpreted and python as interpreted but not compiled. for me, this seems to require splitting ...
🌐
Medium
rameshfadatare.medium.com › is-java-compiled-or-interpreted-lets-clear-the-confusion-94041271942d
Is Java Compiled or Interpreted? Let’s Clear the Confusion! | by Ramesh Fadatare | Medium
March 21, 2025 - Java is compiled to bytecode and then interpreted + JIT compiled by the JVM at runtime. So, Java is both a compiled and interpreted
Find elsewhere
🌐
Baeldung
baeldung.com › home › java › jvm › is java a compiled or interpreted language?
Is Java a Compiled or Interpreted Language? | Baeldung
April 24, 2025 - Every high-level language code, like Java, needs to be translated to machine native code for execution. This translation process can be either compilation or interpretation. However, there is also a third option.
🌐
Medium
medium.com › @pranjalmehta183 › is-java-both-compiled-and-interpreted-080a8dbe8ec5
Is Java Both Compiled and Interpreted Programming Language? | by Pranjal Mehta | Medium
January 9, 2026 - The first step in Java execution is compilation. Java source code (.java) is compiled using the Online Java Compiler ... Unlike C or C++, Java does not compile directly to machine code.
🌐
Blogger
javarevisited.blogspot.com › 2014 › 06 › is-java-interpreted-or-compiled-programming-language.html
Is Java Compiled or Interpreted Programming language? Answer
Knowing how Java achieves platform independence is key to answer this question. If anyone asks this question during interview, then your answer should be both i.e. Java is both compiled and interpreted programming language.
🌐
Wikipedia
en.wikipedia.org › wiki › Java_(programming_language)
Java (programming language) - Wikipedia
1 week ago - Oracle (and others) highly recommend uninstalling outdated and unsupported versions of Java, due to unresolved security issues in older versions. There were five primary goals in creating the Java language: It must be simple, object-oriented, and familiar. It must be robust and secure. It must be architecture-neutral and portable. It must execute with high performance. It must be interpreted, threaded, and dynamic.
🌐
Oracle
forums.oracle.com › ords › apexds › post › what-is-java-compiler-lang-or-interpreter-lang-9120
What is Java (compiler lang / or interpreter lang) - Oracle Forums
August 6, 2001 - Hi, at our company we have a deadly war going on, please help us :) Some programmers, including me, saying that Java is a interpreter language, because the bytecode cant run on a processor, because ...
🌐
Quora
quora.com › Is-Java-a-compiled-programming-language
Is Java a compiled programming language? - Quora
Answer (1 of 3): You were expecting a yes or no answer? Read on… High-level programming languages are not inherently compiled or interpreted. Some are more typically implemented as compilers, and some are more typically implemented as interpreters. But show me a compiler implementation of ...
🌐
Quora
quora.com › Is-Java-a-compiled-language-or-interpreted-What-is-the-difference-What-is-the-JIT-compiler
Is Java a compiled language or interpreted? What is the difference? What is the JIT compiler? - Quora
Answer (1 of 20): Both. First let me explain what a compiler is: A compiler is a program that translates from one language to another. Often the target language is machine code, but it does not have to be. For example a program that translates javascript to C fits the definition of a compiler. ...
🌐
Quora
quora.com › Is-Java-a-compiled-or-interpreted-language-5
Is Java a compiled or interpreted language? - Quora
Answer (1 of 3): Java is compiled to an intermediate representation which is the “machine language” of the Java Virtual Machine. When the program is executed the language of the Java Virtual Machine is translated by the Java Virtual Machine ...
🌐
ScienceDirect
sciencedirect.com › topics › engineering › interpreted-language
Interpreted Language - an overview | ScienceDirect Topics
Java is an object-oriented language developed by Sun Microsystems that allows the development of platform-independent software while also providing some significant housekeeping capabilities to the developer. Fundamentally, Java is a compiled language that is interpreted in real time by a virtual ...
🌐
Quora
codingcheats.quora.com › Is-Java-a-compiled-or-interpreted-language
Is Java a compiled or interpreted language? - CodingCheats.io - Quora
While it is true that many languages ... was usually interpreted, but could be compiled. That said, the answer to Java is neither and both....
🌐
GeeksforGeeks
geeksforgeeks.org › compiler design › difference-between-compiled-and-interpreted-language
Difference between Compiled and Interpreted Language - GeeksforGeeks
July 12, 2025 - A compiled language is a programming language that is generally compiled and not interpreted. It is one where the program, once compiled, is expressed in the instructions of the target machine; this machine code is undecipherable by humans.
🌐
Filo
askfilo.com › american national curriculum › smart solutions › java is called an interpreted language, yet java is a compiled
Java is called an interpreted language, yet Java is a compiled language t..
November 4, 2025 - Java is called a compiled language because it uses a compiler to produce bytecode. It is also called an interpreted language because the JVM interprets (and sometimes compiles) the bytecode at runtime.
Top answer
1 of 5
53

The answer to your question:

Can every language be categorized as either compiled or interpreted?

Is "No", but not for the reason you think it is. The reason is not that there is a third missing category, the reason is that the categorization itself is nonsensical.

There is no such thing as a "compiled language" or an "interpreted language". Those terms are not even wrong, they are nonsensical.

Programming languages are sets of abstract mathematical rules, definitions, and restrictions. Programming languages aren't compiled or interpreted. Programming languages just are. [Credit goes to Shriram Krishnamurthi who said this in an interview on Channel 9 years ago (at about 51:37-52:20).]

In fact, a programming language can perfectly exist without having any interpreter or compiler! For example, Konrad Zuse's Plankalkül which he designed in the 1930s was never implemented during his lifetime. You could still write programs in it, you could analyze those programs, reason about them, prove properties about them … you just couldn't execute them. (Well, actually, even that is wrong: you can of course run them in your head or with pen and paper.)

Compilation and interpretation are traits of the compiler or interpreter (duh!), not the programming language. Compilation and interpretation live on a different level of abstraction than programming languages: a programming language is an abstract concept, a specification, a piece of paper. A compiler or interpreter is a concrete piece of software (or hardware) that implements that specification. If English were a typed language, the terms "compiled language" and "interpreted language" would be type errors. [Again, credit to Shriram Krishnamurthi.]

Every programming language can be implemented by a compiler. Every programming language can be implemented by an interpreter. Many modern mainstream programming languages have both interpreted and compiled implementations. Many modern mainstream high-performance programming language implementations have both compilers and interpreters.

There are interpreters for C and for C++. On the other hand, every single current major mainstream implementation of ECMAScript, PHP, Python, Ruby, and Lua has a compiler. The original version of Google's V8 ECMAScript engine was a pure native machine code compiler. (They went through several different designs, and the current version does have an interpreter, but for many years, it didn't have one.) XRuby and Ruby.NET were purely compiled Ruby implementations. IronRuby started out as a purely compiled Ruby implementation, then added an interpreter later in order to improve performance. Opal is a purely compiled Ruby implementation.

Some people might say that the terms "interpreted language" or "compiled language" make sense to apply to programming languages that can only be implemented by an interpreter or by a compiler. But, no such programming language exists. Every programming language can be implemented by an interpreter and by a compiler.

For example, you can automatically and mechanically derive a compiler from an interpreter using the Second Futamura Projection. It was first described by Prof. Yoshihiko Futamura in his 1971 paper Partial Evaluation of Computation Process – An approach to a Compiler-Compiler (Japanese), an English version of which was republished 28 years later. It uses Partial Evaluation, by partially evaluating the partial evaluator itself with respect to the interpreter, thus yielding a compiler.

But even without such complex highly-academic transformations, you can create something that is functionally indistinguishable from compilation in a much simpler way: just bundle together the interpreter with the program to be interpreted into a single executable.

Another possibility is the idea of a "meta-JIT". (This is related in spirit to the Futamura Projections.) This is e.g. used in the RPython framework for implementing programming languages. In RPython, you write an interpreter for your language, and then the RPython framework will JIT-compile your interpreter while it is interpreting the program, thus producing a specialized compiled version of the interpreter which can only interpret that one single program – which is again indistinguishable from compiling that program. So, in some sense, RPython dynamically generates JIT compilers from interpreters.

The other way around, you can wrap a compiler into a wrapper that first compiles the program and then directly executes it, making this wrapped compiler indistinguishable from an interpreter. This is, in fact, how the Scala REPL, the C♯ REPL (both in Mono and .NET), the Clojure REPL, the interactive GHC REPL, and many other REPLs are implemented. They simply take one line / one statement / one expression, compile it, immediately run it, and print the result. This mode of interacting with the compiler is so indistinguishable from an interpreter, that some people actually use the existence of a REPL for the programming language as the defining characteristic of what it means to be an "interpreted programming language".

Note, however, that you can't run a program without an interpreter. A compiler simply translates a program from one language to another. But that's it. Now you have the same program, just in a different language. The only way to actually get a result of the program is to interpret it. Sometimes, the language is an extremely simple binary machine language, and the interpreter is actually hard-coded in silicone (and we call it a "CPU"), but that's still interpretation.

Some people say that you can call a programming language "interpreted" if the majority of its implementations are interpreters. Well, let's just look at a very popular programming language: ECMAScript. There are a number of production-ready, widely-used, high-performance mainstream implementations of ECMAScript, and every single one of them includes at least one compiler, some even multiple compilers. So, according to this definition, ECMAScript is clearly a compiled language.

You might also be interested in this answer of mine, which explains the differences and the different means of combining interpreters, JIT compilers and AOT compilers and this answer dealing with the differences between an AOT compiler and a JIT compiler.

It is possible to categorize language implementations to some degree. In general, we have the distinction between

  • compilers and
  • interpreters (if the interpreter interprets a language that is not meant for humans, it is also often called a virtual machine)

Within the group of compilers, we have the temporal distinction when the compiler is run:

  • Just-In-Time compilers run while the program is executing
  • Ahead-Of-Time compilers run before the program starts

And then we have implementations which combine interpreters and compilers, or combine multiple compilers, or (much more rare) multiple interpreters. Some typical combinations are

  • mixed-mode execution engines which combine an interpreter and a JIT compiler that both process the same program at the same time (examples: Oracle HotSpot JVM, IBM J9 JVM)
  • multi-phase [I invented that term; I don't know of a widely-used one] execution engines, where the first phase is a compiler that compiles the program to a language more suitable for the next phase, and then a second phase which processes that language. (There could be more phases, but two is typical.) As you can probably guess, the second phase can again use different implementation strategies:
    • an interpreter: this is a typical implementation strategy. Often, the language that is interpreted is some form of bytecode that is optimized for "interpretability". Examples: CPython, YARV (pre-2.6), Zend Engine
    • a compiler, which makes this a combination of two compilers. Typically, the first compiler translates the language into some form of bytecode that is optimized for "compilability" and the second compiler is an optimizing compiler that is specific to the target platform
    • a mixed-mode VM. Examples: YARV post-2.6, Rubinius, SpiderMonkey, SquirrelFish Extreme, Chakra

But, there are still others. Some implementations use two compilers instead of a compiler and an interpreter to get the same benefits as a mixed-mode engines (e.g. the first few years, V8 worked this way).

RPython combines a bytecode interpreter and a JIT, but the JIT does not compile the user program, it compiles the bytecode interpreter while it interprets the user program! The reason for this is that RPython is a framework for implementing languages, and in this way, a language implementor only has to write the bytecode interpreter and gets a JIT for free. (The most well-known user of RPython is of course PyPy.)

The Truffle framework interprets a language-agnostic AST, but at the same time it specializes itself to the specific AST, which is kind-of like compilation but also kind-of not. The end result is that Truffle can execute the code extremely fast, without knowing too much about the language-specifics. (Truffle is also a generic framework for language implementations.) Because the AST is language-agnostic, you can mix and match multiple languages in the same program, and Truffle is able to perform optimizations across languages, such as inlining a Ruby method into an ECMAScript function etc.

Macros and eval are sometimes cited as features that cannot possibly be compiled. But that is wrong. There are two simple ways of compiling macros and eval. (Note that for the purpose of compilation, macros and eval are somewhat dual to each other, and can be handled using similar means.)

  1. Using an interpreter: for macros, you embed an interpreter into the compiler. For eval, you embed an interpreter into the compiled program or into the runtime support libraries.
  2. Using a compiler: for macros, you compile the macro first, then embed the compiled macro into your compiler and compile the program using this "extended" compiler. For eval, you embed a compiler into the compiled program or into the runtime support libraries.
2 of 5
14

If we are being pedantic, there is no such thing as a compiled or interpreted language, since any language could be in principle be implemented either by a compiler or an interpreter. However, most languages follow a relatively consistent implementation strategy. C++ is almost always compiled to native code. Python is almost always run via a bytecode interpretor. Java is almost always run via a JIT comiler. So, if we don't insist on an obtuse pedanticness, it does make sense to talk about compiled or interpreted languages.

However, language implementation strategy does not neatly fit into the compiled/interpreted dichotomy. Essentially no languages are strictly interpreted, executed directly from the source. This would be very slow. Instead, virtually all "interpreted" language implementations compile the source into something (often bytecode) which can be more effeciently executed. On top of this, some implementations JIT compile that bytecode into native code at run time. Even languages that we think of as being compiled often contain some amount of interpretation. For example, printf in C is effectively an interpreter of the format string.

So, I would argue that it doesn't make sense to try and categorize languages into compiled or interpreted. Pretty much any languages is some degree of hybrid of the two approaches. (And yes, if we are pedantic, it is language implementations not languages which are compiled/interpreted).