|
Java is compiled to Java byte code. It cannot be interpreted in its source form. There's nothing preventing it to be, but as far as I know, there are no interpreters for it. Python on the other hand can be interpreted from source, and that's the default behavior, making Python an interpreted language. This makes Java a compiled language, even though it is compiled to machine code for a machine that doesn't exist. Java Byte Code is an assembly language, and in fact, Sun had at one point machines that were natively using Java Byte Code instruction sets. Now Java Byte Code is trickier. You could consider it to be interpreted or compiled or both. It is fair to say that in general it is interpreted, but it is just as fair to say it is in general compiled. What matters most though is to understand that modern JVMs make use of a JIT compiler and optional AOT compilers. In the latter mode, you can compile Java Byte Code to native machine executables ahead of time or pre-runtime and no JVM beyond that point is required. So you can distribute the app as a self-contained executable. In most cases though, this will be less performant in the average and peak performance, but it will speed up the worst case, such as start time. In the former mode, the JVM will analyze runtime behavior and based on the frequency of use of various code paths, it will either compile the code to native machine code (cache the compiled code), and then run the freshly compiled code block, or it will choose to interpret the byte code directly. This allows aggressive optimization from information which is only available or easily available at runtime when performing compilation. |
Actual sourced-based interpretation is _very_ slow, and pretty rare in anything that sees meaningful real world use. Ruby was, back when it was an order of magnitude slower than Python, but no other example jumps readily to mind, and Ruby went bytecode with the release of 1.9 in 2007.