Features of Java
Java was designed from the ground up with a specific set of goals: write code once and run it anywhere, make memory management automatic, keep the language safe and robust, and support concurrent programming natively. These goals translate directly into the features you will use every day.
1. Platform Independence (Write Once, Run Anywhere)
This is Java’s most famous feature. When you compile a .java file, javac produces .class files containing bytecode — an intermediate representation that is not tied to any CPU or operating system. The JVM on each target platform interprets (and JIT-compiles) that same bytecode.
public class PlatformDemo {
public static void main(String[] args) {
System.out.println("Running on: " + System.getProperty("os.name"));
System.out.println("JVM version: " + System.getProperty("java.version"));
}
}
Output (example on Linux):
Running on: Linux
JVM version: 21.0.3
The exact same .class file produces equivalent output on Windows or macOS — only the first line changes. See How a Java Program Runs for the full compilation-to-execution story.
2. Object-Oriented Programming
Java is built entirely around objects — instances of classes that combine state (fields) and behaviour (methods). The four pillars — encapsulation, inheritance, polymorphism, and abstraction — are first-class citizens of the language.
public class Animal {
private String name; // encapsulation: private field
public Animal(String name) { this.name = name; }
public void speak() { System.out.println(name + " makes a sound."); }
}
public class Dog extends Animal { // inheritance
public Dog(String name) { super(name); }
@Override
public void speak() { System.out.println("Woof!"); } // polymorphism
}
Tip: Everything in Java lives inside a class — even the
mainmethod. This is different from languages like C or Python where top-level functions exist outside any class.
Explore these ideas in depth starting at OOP Concepts.
3. Strongly Typed and Statically Typed
Every variable and expression in Java has a type known at compile time. The compiler rejects type mismatches before your program ever runs, catching a whole category of bugs early.
int count = 10;
String message = "hello";
// This won't compile — the compiler catches the error immediately:
// count = message; // ❌ incompatible types: String cannot be converted to int
Java 10 introduced the var keyword for local variable type inference, which lets the compiler infer the type without sacrificing static typing:
var list = new java.util.ArrayList<String>(); // type is still ArrayList<String> at compile time
list.add("Java");
Learn more in Java 10: var and Data Types.
4. Automatic Memory Management (Garbage Collection)
Java manages heap memory for you. You create objects with new; when no more references to an object exist, the Garbage Collector (GC) reclaims that memory automatically. There is no free() or delete.
public class GCDemo {
public static void main(String[] args) {
for (int i = 0; i < 1_000_000; i++) {
String s = new String("object " + i); // created and quickly becomes unreachable
}
// No memory leak — the GC cleans up unreachable objects automatically
System.out.println("Done — no manual cleanup needed.");
}
}
Output:
Done — no manual cleanup needed.
The modern GC implementations (G1, ZGC, Shenandoah) in Java 21 can handle heaps of hundreds of gigabytes with sub-millisecond pause times. See Garbage Collection Deep-Dive for tuning strategies.
5. Multithreading
Java has built-in language and library support for running multiple threads concurrently. The Thread class and Runnable interface have been in Java since version 1.0, and Java 21 adds virtual threads (Project Loom) that make concurrent I/O-bound code dramatically simpler and cheaper.
public class ThreadDemo {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> System.out.println("Thread 1 running"));
Thread t2 = new Thread(() -> System.out.println("Thread 2 running"));
t1.start();
t2.start();
t1.join();
t2.join();
}
}
Output (order may vary):
Thread 1 running
Thread 2 running
Note: The output order is non-deterministic — the OS thread scheduler decides which thread runs first.
Explore the full threading model in Multithreading and Virtual Threads.
6. Robust and Reliable
Java was designed to catch errors as early as possible. Three mechanisms work together:
- Compile-time type checking — the compiler enforces types and catches obvious mistakes.
- Exception handling — the try-catch-finally block forces you to acknowledge that operations can fail.
- No pointers — you work with references, not raw memory addresses, eliminating segfaults and buffer overflows.
public class RobustDemo {
public static int divide(int a, int b) {
if (b == 0) throw new ArithmeticException("Cannot divide by zero");
return a / b;
}
public static void main(String[] args) {
try {
System.out.println(divide(10, 0));
} catch (ArithmeticException e) {
System.out.println("Caught: " + e.getMessage());
}
}
}
Output:
Caught: Cannot divide by zero
7. Secure
Java’s security model operates at multiple levels:
- Bytecode verifier — the JVM checks that loaded bytecode obeys type safety rules before executing it.
- Class loader — isolates classes from different sources (see Class Loaders & Class Loading).
- Security Manager (legacy) / module system (Java 9+) — restricts what code can access at runtime.
- No direct memory access — pointer arithmetic is impossible, removing entire classes of exploits.
8. High Performance via JIT Compilation
Java is often described as “slow” — a reputation it outgrew years ago. The HotSpot JIT compiler monitors which methods execute most frequently (“hot spots”) and compiles them to optimised native machine code at runtime. Long-running Java services frequently match or exceed the throughput of equivalent C++ applications.
public class JITDemo {
public static long sum(long n) {
long total = 0;
for (long i = 1; i <= n; i++) total += i;
return total;
}
public static void main(String[] args) {
// After a few warm-up iterations the JIT kicks in and this gets very fast
for (int i = 0; i < 5; i++) {
long start = System.nanoTime();
long result = sum(100_000_000L);
long elapsed = System.nanoTime() - start;
System.out.printf("sum=%d time=%dms%n", result, elapsed / 1_000_000);
}
}
}
You will typically see the elapsed time drop across iterations as the JIT warms up. Dive deeper in JIT Compilation & Bytecode.
9. Rich Standard Library
The Java Class Library (JCL) ships with the JDK and covers an enormous surface area out of the box:
| Package | What it provides |
|---|---|
java.util | Collections, Date/Time, Random, Scanner |
java.io / java.nio | File I/O, channels, memory-mapped files |
java.net | Sockets, URL handling, HTTP |
java.util.concurrent | Thread pools, locks, atomic variables |
java.util.stream | Functional-style data pipelines |
java.sql | JDBC database connectivity |
java.lang.reflect | Reflection and dynamic class inspection |
You rarely need a third-party library for basic tasks. Explore the collections side in Collections Framework and streams in Stream API.
10. Distributed and Network-Friendly
Java was built with networking in mind. Socket Programming, RMI (Remote Method Invocation), and HttpURLConnection / HttpClient (Java 11+) are all part of the standard library. Java EE (now Jakarta EE) and frameworks like Spring Boot run the majority of the world’s enterprise web services.
11. Dynamic and Extensible
Despite being statically typed, Java supports dynamic loading — classes can be loaded at runtime without recompilation. This powers plugin architectures, dependency injection frameworks (Spring, Guice), and application servers that deploy new code without restarting.
// Load and instantiate a class by name at runtime
Class<?> clazz = Class.forName("java.util.ArrayList");
Object instance = clazz.getDeclaredConstructor().newInstance();
System.out.println(instance.getClass().getSimpleName()); // ArrayList
Output:
ArrayList
See Reflection API for the full picture.
Under the Hood
Several features that look like “language magic” are actually implemented at the JVM level:
- Platform independence relies on a strict bytecode specification. Every JVM implementation — Oracle HotSpot, OpenJ9, GraalVM — must execute the same bytecode identically.
- Garbage collection uses a generational heap: most objects die young (collected cheaply in the young generation), while survivors are promoted to the old generation and collected less often.
- Multithreading maps Java threads to OS threads (1:1) by default. Java 21 virtual threads use a M:N mapping — millions of virtual threads multiplex over a small pool of carrier (OS) threads, making high-concurrency I/O workloads practical without async/callback complexity.
- JIT compilation goes beyond simple translation: it inlines methods, eliminates dead code, performs escape analysis to allocate some objects on the stack instead of the heap, and speculatively optimises based on runtime type feedback.
These mechanics explain why Java code that looks expensive (lots of small object allocations, heavy use of interfaces) often performs better than you would expect.
Quick Reference
| Feature | Key benefit |
|---|---|
| Platform independence | One .jar runs on any OS / CPU |
| Object-oriented | Models real-world complexity naturally |
| Strong static typing | Bugs caught at compile time |
| Automatic GC | No manual memory management |
| Multithreading | Concurrent code built into the language |
| Robust exceptions | Forces explicit error handling |
| Security | Bytecode verification + no raw pointers |
| JIT performance | Native-speed execution for hot code |
| Rich standard library | Batteries included for most tasks |
| Dynamic class loading | Plugins, DI frameworks, hot deployment |
Related Topics
- History of Java — understand why Java was designed this way and how it evolved over 30 years.
- JVM Architecture — the runtime machinery behind platform independence, JIT, and GC.
- Garbage Collection Deep-Dive — how the G1 and ZGC collectors work and how to tune them.
- OOP Concepts — encapsulation, inheritance, polymorphism, and abstraction explained with examples.
- Multithreading — Java’s threading model from
ThreadtoExecutorServiceto virtual threads. - Java 21 LTS Features — the latest additions: virtual threads, records, sealed classes, and pattern matching.