Compiled Code
: The programmer writes the code, a different program called the Compiler translates that into machine code (instructions specific to that CPU in the computer) before the programmer written code ever runs. Think of an.exe file. The pro is that since the computer
can execute the instructions instantaneously, it is incredibly fast. The con being that it becomes platform-specific. The same .exe file won't run on a Mac and you would
have to re-translate the original program again. Interpreted Code
: In a purely interpreted language (like Python or early Ruby), there is no pre-translation. Instead, a program called an Interpreter reads your code line-by-line while the program is running, converts it into machine code, and then the machine runs it. The pro is that the same programmer-written code can now run on any computer as long as that computer has the right interpreter installed. The con is that it is slower. The computer has to "waste" time translating while it's trying to work. If you have a loop that runs 1,000 times, the interpreter translates those same lines 1,000 times.What Java does
: Java combines the two steps:javac HelloWorld.java. This will output HelloWorld.class intermediate
file that can't be directly understood by you or the computer. Only the JVM can understand this. java HelloWorld, the JVM interprets the bytecode, converting it into machine code that the computer can
understand. If the compiler sees a piece of bytecode being used a lot, it will use the JVM (HotSpot) JIT to compile that specific part into native machine code on
the fly so that it doesn't have to interpret it every time. Ahead-of-Time compilation
: Java also has tried Ahead-of-Time compilation. Java must be turned into Bytecode first. AOT is the process of taking that universal Bytecode and converting it into a native binary before you ship it. The most significant way AOT lives in Java today is through GraalVM. Why? In "Serverless" computing (like AWS Lambda), you want your code to start in milliseconds. A traditional JIT-based Java app might take seconds to start - which is too slow. GraalVM AOT makes Java competitive with languages like Go or Rust for these tasks.Polymorphism
: Meaning 'many forms', this is the ability for objects of different classes to be treated as objects of a common superclass, allowing a single action (like a method call) to be performed in different ways depending on the object's actual type.Inheritance
: A mechanism that allows a new class (the subclass) to acquire the properties and behaviors of an existing class (the superclass), promoting code reuse and establishing a hierarchy of objects.Encapsulation
: bundle data and the methods that operate on that data together within a single unit - the Class, hiding the internal state from the outside world..java filename extension. It
is a text file that contains (among other things) one or more class definitions. public class per .java file and, if the public class is present, then the name of the .java file must match
the name of the public class. Because of this rule, the compiler can instantly locate the source code for a class (e.g., ProcessPayload will always be in
ProcessPayload.java), drastically speeding up compilation times for large projects. Compile the program
:javac Example.java. This creates a file called Example.class that contains the compiled
bytecode. Run the Program
:java Example. Invokes the JVM to execute the bytecode. Note that you are passing the class name, and not the
file name. ie you are not using java Example.class. .class file for every single inner class.
Because they don't have unique top-level names, Java names them using a $ symbol: Outer.classOuter$Inner.class (For member inner classes)Outer$1LocalInner.class (For local/anonymous classes, using a number to distinguish them)
// Saved in a file named Outer.java
class Outer {
// 1. Member Inner Class
// Compiles to: Outer$Inner.class
class Inner {
void display() {
System.out.println("Inside member inner class.");
}
}
void someMethod() {
// 2. Local Inner Class inside a method
// Compiles to: Outer$1LocalInner.class
class LocalInner {
void print() {
System.out.println("Inside local inner class.");
}
}
// Instantiating and using the local class within the method
LocalInner local = new LocalInner();
local.print();
}
}