The key that allows Java to solve both the security and the portability problems just described is that the output of a Java compiler is not executable code. Rather, it is bytecode. Bytecode is a highly optimized set of instructions designed to be executed by the Java run-time system, which is called the Java Virtual Machine (JVM). That is, the Java Virtual Machine is an interpreter for bytecode.
Translating a Java program into bytecode makes it much easier to run a program in a wide variety of environments. The reason is straightforward: only the Java Virtual Machine needs to be implemented for each platform. Once the run-time package exists for a given system, any Java program can run on it.
The fact that a Java program is interpreted also helps make it secure. Because the execution of every Java program is under the control of the JVM, the JVM can contain the program and prevent it from generating side effects outside the system.
Sun provides a facility called lust In Time (JIT) compiler for bytecode. It is not possible to compile an entire Java program into executable code all at once, because Java performs various run-time checks that can be done only at run time. JIT compiles the code 3.S and when needed.