A language tour

The Ubiquity of Java

Write once, run anywhere. Three billion devices. The language that made the JVM, and then the JVM outlasted the language wars.

scroll

01 — The JVM

One bytecode, every platform

Java's promise in 1995 was radical: compile once, run anywhere. The Java Virtual Machine abstracts the hardware. The same .class file runs on Windows, Linux, macOS, Android, and a Blu-ray player's firmware. No other platform achieved this breadth.

"Java is the most popular programming language in the world — not because it's the best at anything in particular, but because it's reliably good at everything."

— James Gosling, creator of Java
HelloWorld.java
// The program every Java developer has written
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

// javac HelloWorld.java  → HelloWorld.class (bytecode)
// java HelloWorld        → runs on any JVM anywhere
//
// The same .class file runs unchanged on:
// Windows x64, Linux ARM, macOS Apple Silicon,
// Android (via ART), embedded JVMs in printers...

The verbosity of public static void main(String[] args) became famous — and later, Java 21 introduced void main() as a preview feature, finally trimming the ceremony from the simplest program.


02 — Generics

Type safety without sacrificing flexibility

Java's generics — added in Java 5 — let you write type-safe collections and algorithms without sacrificing reuse. They're not as powerful as Rust's or Haskell's, but they catch a whole class of runtime errors at compile time and remain one of Java's great contributions to mainstream OOP.

Generics.java
import java.util.*;
import java.util.function.*;

// A generic pair — works for any two types
record Pair<A, B>(A first, B second) {
    public Pair<B, A> swap() {
        return new Pair<>(second, first);
    }
}

// Bounded type parameters — T must be Comparable
public static <T extends Comparable<T>> T max(List<T> list) {
    return list.stream().max(Comparator.naturalOrder()).orElseThrow();
}

// Diamond operator infers type arguments
var scores = new HashMap<>();  // Map<String,Integer> inferred
scores.put("Alice", 95);
scores.put("Bob",   88);

Java records (Java 16) are the modern replacement for plain data classes. One line declares the type with a canonical constructor, equals, hashCode, and toString — no Lombok required.


03 — Streams & Lambdas

Functional pipelines in an OOP world

Java 8 added lambdas and the Stream API — a delayed but decisive step toward functional style. Streams let you express data transformations as pipelines of lazy operations. Combined with method references, the result is remarkably expressive for a statically typed language.

Streams.java
import java.util.*;
import java.util.stream.*;

record Employee(String name, String dept, double salary) {}

var employees = List.of(
    new Employee("Alice", "Eng",   120_000),
    new Employee("Bob",   "Eng",   95_000),
    new Employee("Carol", "HR",    80_000),
    new Employee("Dave",  "Eng",   110_000)
);

// Average salary per department
var avgByDept = employees.stream()
    .collect(Collectors.groupingBy(
        Employee::dept,
        Collectors.averagingDouble(Employee::salary)
    ));
// {Eng=108333.33, HR=80000.0}

Method references like Employee::dept are not string-based reflection — they're typed lambdas. The compiler checks that dept exists and returns the right type. Refactoring is safe.


04 — Sealed Classes & Pattern Matching

Algebraic types, Java style

Modern Java — from version 17 onward — has sealed classes and pattern matching in switch. Finally, the exhaustive type hierarchies you once needed visitors and double-dispatch for can be expressed cleanly, with compiler-checked completeness.

PatternMatching.java
// Sealed interface — only these implementations are allowed
sealed interface Shape
    permits Circle, Rectangle, Triangle {}

record Circle(double radius)     implements Shape {}
record Rectangle(double w, double h) implements Shape {}
record Triangle(double b, double h)  implements Shape {}

double area(Shape s) {
    return switch (s) {
        case Circle    c  -> Math.PI * c.radius() * c.radius();
        case Rectangle r  -> r.w() * r.h();
        case Triangle  t  -> 0.5 * t.b() * t.h();
        // No default needed — sealed = exhaustive
    };
}

Because Shape is sealed, the compiler knows exactly which subtypes exist. The switch expression is exhaustive without a default branch — adding a new subtype forces you to handle it everywhere.


05 — Virtual Threads

Millions of threads, one JVM

Java 21's virtual threads — Project Loom — bring structured concurrency to Java without changing the programming model. You write blocking code; the JVM schedules millions of lightweight threads on a small OS thread pool. The simplicity of synchronous code, the scalability of async.

VirtualThreads.java
import java.util.concurrent.*;

// Spawn 100,000 virtual threads — lightweight, cheap
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 100_000).forEach(i ->
        executor.submit(() -> {
            // Blocking I/O — the JVM parks the virtual thread,
            // frees the OS thread for other work
            var result = callDatabase(i);
            process(result);
        })
    );
}  // executor.close() waits for all tasks

// Structured concurrency (Java 21 preview)
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
    var user  = scope.fork(() -> fetchUser(userId));
    var order = scope.fork(() -> fetchOrder(orderId));
    scope.join().throwIfFailed();
    // Both calls happened in parallel
}

Virtual threads are not green threads or coroutines — they're full Java threads with their own stack, monitored by the debugger, visible in stack traces. The programming model is unchanged; only the implementation is different.


06 — The Whole Picture

Why Java still dominates

🌍

Three Billion Devices

Banking systems, enterprise software, Android apps, big data pipelines — Java is everywhere you don't see it.

🔄

Backwards Compatibility

Java code from 2001 still compiles and runs on Java 21. No other major language has maintained this discipline for so long.

GraalVM

Ahead-of-time native compilation via GraalVM produces instant-startup binaries from Java code. No JVM warmup required.

📦

Maven Central

The world's largest repository of reusable libraries. If a problem exists, a battle-tested Java library almost certainly solves it.

🛠️

Tooling

IntelliJ IDEA's Java support is the benchmark for IDE intelligence. Refactoring, analysis, and completion that actually works.

🚀

Modern Java

Records, sealed classes, pattern matching, virtual threads, text blocks — Java releases every 6 months and means it.