← thecodex.expert · The Codex Family of Knowledge

Free · No account · Official sources only

Java — Cradle to Mastery

A complete, structured path through Java — from your first class to virtual threads and the modern data-modeling features that reshaped the language after 2020. Every lesson points at reference pages already written and verified on this site. Free, no account, no sign-up.

30 lessons 6 stages ~27 hours of reading 10 projects Java 25 LTS (Sept 2025) · curriculum current as of 2026
Start Lesson 1 → Browse the reference instead

How this course works

1
Follow the stages in orderEach stage assumes the one before it. Stage 3 in particular assumes Stage 2 cold.
2
Read the tab the lesson namesReference pages have Beginner, Intermediate and Expert tabs. Read only what the lesson asks for on a first pass.
3
Run every exampleKeep the playground open in a second tab. Reading code you have not run is how misunderstandings survive.
4
Build after each stageDo not save all ten projects for the end. Pick one up as soon as a stage gives you enough to attempt it.
Casual pace: ~10 weeks at 4 hours a week
Steady pace: ~5 weeks at 8 hours a week
Intensive: ~2 weeks full-time
STAGE 0

Before You Start

Thirty years old and still the backbone of enterprise software, Android, and half the world's backend systems. These two lessons explain why, and get a JDK installed.

LESSON 1

What is Java?

James Gosling's 1995 promise — write once, run anywhere — still the deal today

Java was built at Sun Microsystems under James Gosling with one central bet: compile to bytecode that runs unmodified on any machine with a JVM. Three decades and one Oracle acquisition later, that bet is why Java still runs most of the world's banking systems, all of Android, and a huge share of backend services you use daily without knowing it.

📚 🟩 Read the Beginner tab only.
Key focus: Why bytecode-and-a-JVM was the actually novel idea in 1995, and where Java dominates today.
⏱ 30 min
Required Reading
→
What is Java? — The Codex

Java's origin at Sun Microsystems, the write-once-run-anywhere bytecode model, the six-month release cadence since Java 10, and where Java 25 LTS sits in that timeline.

LESSON 2

Setup and JDK

JDK, JRE, JVM — three acronyms that mean genuinely different things

The JDK is what you install to write Java; the JRE is a runtime-only subset most people no longer install separately; the JVM is the actual virtual machine both of them ship. Getting this straight up front avoids a surprising amount of confused troubleshooting later.

📚 🟩 Read the Beginner tab only.
Key focus: Installing a JDK, telling JDK/JRE/JVM apart, and compiling and running your first class from the command line.
⏱ 30 min
Required Reading
→
Setup and JDK — The Codex

Installing a JDK (25 LTS), JAVA_HOME, javac and java from the command line, and IDE setup.

STAGE 1

Language Fundamentals

The syntax you will use in nearly every file: variables, control flow, methods, strings, and the standard library's biggest wins. Five lessons before objects properly begin.

LESSON 3

Variables and Types

8 primitive types, String, autoboxing, and var inference

Java is statically and strongly typed, with exactly 8 primitives and everything else an object. Autoboxing quietly converts between the two, which is convenient until it silently costs you performance or triggers a subtle bug — both worth understanding before you rely on either.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The primitive/object split, what autoboxing actually does, and when `var` helps versus obscures.
⏱ 1 hours
Required Reading
→
Variables and Types — The Codex

The 8 primitive types, String basics, autoboxing/unboxing, type casting, and var's local type inference.

LESSON 4

Control Flow

if/for/while are familiar; the switch expression is the modern rewrite

Java's basic control flow is standard C-family syntax you likely already know. What is worth real attention is the modern switch *expression* — arrow-form, no fall-through, and (with pattern matching) exhaustive — which is a genuinely different construct from the old switch statement, not just new syntax.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The old switch statement's fall-through pitfall versus the modern switch expression's arrow syntax.
⏱ 45 min
Required Reading
→
Control Flow — The Codex

if/else, for/while/do-while, enhanced for, the classic switch statement, and the modern switch expression.

LESSON 5

Methods

No standalone functions — every method lives inside a class

Unlike Python, JavaScript, or Go, Java has no free-floating functions: every method belongs to a class, static or instance. Overloading — the same name with different parameter signatures — is resolved at compile time based on the declared types you pass, not the runtime type.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why every method needs a class, and how overload resolution picks a signature at compile time.
⏱ 45 min
Required Reading
→
Methods — The Codex

Method syntax, parameters and return types, static vs instance methods, overloading, and varargs.

LESSON 6

String Handling

Strings are immutable and pooled — why == on strings is a classic bug

Java interns string literals into a shared pool, so two literals with the same text can be the same object — which is exactly why comparing strings with <code>==</code> sometimes appears to work and sometimes doesn't. <code>.equals()</code> is the only correct comparison, always.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Why string immutability and pooling make `==` unreliable, and StringBuilder's role for repeated concatenation.
⏱ 45 min
Required Reading
→
String Handling — The Codex

String immutability, the string pool, .equals() vs ==, StringBuilder, text blocks, and common String methods.

LESSON 7

Standard Library

Three decades of APIs — including real replacements for old, flawed ones

java.util, java.time, java.util.Optional and friends represent thirty years of accretion, some of it excellent and some of it superseded by its own successor (java.time replacing the notoriously broken java.util.Date, for instance). Knowing which era an API is from tells you whether to reach for it.

📚 ⚡ Intermediate.
Key focus: Which parts of the standard library are the current best practice, and which are legacy APIs to avoid in new code.
⏱ 1 hours
Required Reading
→
Standard Library — The Codex

java.time (LocalDate/LocalDateTime/Duration), java.util.Objects, Math, formatting, and legacy APIs superseded by better ones.

STAGE 2

Object-Oriented Java — Java's Defining Discipline

Java is fundamentally an object-oriented language, and this is the stage where that identity is built up piece by piece — then the last lesson ties every piece together into one realistic class hierarchy. Eight lessons, the heart of the course.

LESSON 8

Classes and Objects

A class is a blueprint; new allocates an actual object on the heap

Every Java program is built from classes and the objects instantiated from them. This lesson is the foundation the rest of the stage builds on: fields, constructors, the `this` reference, and the distinction between a class (compile-time) and an object (runtime, on the heap).

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: The class-versus-object distinction, constructors, and what actually happens on `new`.
⏱ 1 hours
Required Reading
→
Classes and Objects — The Codex

Class declarations, fields, constructors, the this keyword, object creation, and access modifiers.

LESSON 9

Inheritance and Polymorphism

extends creates is-a; the runtime object decides which override runs

<code>extends</code> establishes an is-a relationship between classes, and polymorphism means the *actual* object at runtime — not the declared reference type — decides which overridden method executes. This dynamic dispatch is what makes interfaces and abstract classes actually useful.

📚 ⚡ Intermediate.
Key focus: Dynamic dispatch: why the runtime type, not the reference type, decides which overridden method runs.
⏱ 1 hours
Required Reading
→
Inheritance and Polymorphism — The Codex

extends, method overriding vs overloading, super, dynamic dispatch, and the Object class's role as universal superclass.

LESSON 10

Interfaces and Abstract Classes

Implement many interfaces, extend only one abstract class

A class can implement any number of interfaces but extend only one abstract (or concrete) class — Java's answer to the diamond problem, and the actual reason interfaces exist as a separate construct from abstract classes rather than a redundant one.

📚 ⚡ Intermediate.
Key focus: Why single inheritance plus multiple interface implementation avoids the diamond problem.
⏱ 1 hours
Required Reading
→
Interfaces and Abstract Classes — The Codex

Interface declarations, default and static interface methods, abstract classes, and when to choose one over the other.

LESSON 11

Enums

A Java enum is a real class — fields, constructors, methods, per-constant bodies

Unlike C-style enums that are just named integers, a Java enum is a full class: it can carry fields, have a constructor, define methods, and even give individual constants their own method bodies. This makes enums a genuine modeling tool, not just a label.

📚 ⚡ Intermediate.
Key focus: Treating an enum as a real class with state and behavior, not just a named-constant list.
⏱ 45 min
Required Reading
→
Enums — The Codex

Enum declarations, enum constructors and fields, methods on enums, per-constant bodies, and EnumMap/EnumSet.

LESSON 12

Records

One line replaces the constructor, getters, equals, hashCode, and toString

A record is an immutable data carrier: declare the fields once and the compiler generates the constructor, accessors, <code>equals</code>, <code>hashCode</code>, and <code>toString</code> for you. It is Java's answer to the boilerplate that made simple data classes tedious for two decades.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: What a record generates automatically, and why immutability is baked into the design rather than optional.
⏱ 45 min
Required Reading
→
Records — The Codex

Record syntax, compact constructors, validation in a compact constructor, and records implementing interfaces.

LESSON 13

Sealed Classes

sealed names every permitted subclass — finalized in Java 17

A <code>sealed</code> class or interface lists exactly which classes are allowed to extend or implement it, closing off the hierarchy to anything the author didn't explicitly permit. This is what makes exhaustive pattern matching possible in the next lesson.

📚 ⚡ Intermediate.
Key focus: How a closed, sealed hierarchy is what makes an exhaustive switch over types actually provable by the compiler.
⏱ 45 min
Required Reading
→
Sealed Classes — The Codex

sealed, permits, non-sealed subclasses, and how sealed hierarchies enable exhaustive pattern matching.

LESSON 14

Pattern Matching

instanceof used to require a separate cast — pattern matching removes it

Before pattern matching, <code>instanceof</code> told you a type but still required a separate, redundant cast to use it. Pattern matching for instanceof and switch collapses the check and the binding into one expression, and combined with sealed types, switch can be checked for exhaustiveness.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Collapsing an instanceof-then-cast into one pattern, and exhaustive switch over a sealed hierarchy.
⏱ 1 hours
Required Reading
→
Pattern Matching — The Codex

Pattern matching for instanceof, record patterns, pattern matching in switch, guards, and exhaustiveness with sealed types.

LESSON 15

Object-Oriented Java, Tied Together

Classes, interfaces, records, sealed types and enums in one realistic hierarchy

This lesson is the synthesis for the stage: the individual pieces you just met — classes, access modifiers, abstract classes, interfaces, inheritance, polymorphism, records, sealed classes, and enums — combined into one realistic class hierarchy, including the builder pattern for constructing complex objects cleanly. Read it once each piece is familiar on its own.

📚 ⚡ Intermediate.
Key focus: Seeing every OOP feature in this stage work together, including where the builder pattern fits.
⏱ 1.25 hours
Required Reading
→
Object-Oriented Java, Tied Together — The Codex

Classes, access modifiers, abstract classes, interfaces, inheritance, polymorphism, records, sealed classes, the builder pattern, and enums together.

STAGE 3

Collections, Generics & Functional Style

How Java stores and processes data at scale, and the functional-style API layered on top of it since Java 8. Four lessons.

LESSON 16

Collections and Generics

ArrayList, HashMap, generics, wildcards, and type erasure

The Collections Framework — ArrayList, HashMap, HashSet, LinkedList, PriorityQueue, ArrayDeque — is what you reach for constantly, and generics are what make it type-safe. Type erasure is the one genuinely surprising part: generic type information does not exist at runtime, only at compile time.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Picking the right collection for the job, and what type erasure means generics can't do at runtime.
⏱ 1.25 hours
Required Reading
→
Collections and Generics — The Codex

ArrayList, HashMap, HashSet, LinkedList, PriorityQueue, ArrayDeque, generic classes and methods, wildcards, and type erasure.

LESSON 17

Exception Handling

Checked vs unchecked, try-with-resources, and exception chaining

Java's checked-exception system is genuinely unusual among mainstream languages: the compiler forces you to declare or handle certain exceptions. try-with-resources then guarantees cleanup automatically for anything implementing AutoCloseable, which is what makes it the modern default over manual finally blocks.

📚 ⚡ Intermediate.
Key focus: The checked-vs-unchecked distinction, and why try-with-resources replaced manual finally-block cleanup.
⏱ 1 hours
Required Reading
→
Exception Handling — The Codex

try-catch-finally, checked vs unchecked exceptions, try-with-resources, custom exceptions, multi-catch, and exception chaining.

LESSON 18

Streams and Lambdas

Lambdas, method references, and Collectors turn loops into pipelines

The Stream API, introduced in Java 8, lets you describe a data transformation as a declarative pipeline — filter, map, collect — instead of a hand-written loop with mutable accumulator state. Lambdas and method references are the syntax that makes passing behavior around finally lightweight in Java.

📚 ⚡ Intermediate.
Key focus: Thinking in pipelines instead of loops, and when a parallel stream actually helps versus just adds overhead.
⏱ 1.25 hours
Required Reading
→
Streams and Lambdas — The Codex

Lambda syntax, functional interfaces, method references, the Stream API, Collectors and groupingBy, and parallel streams.

LESSON 19

Optional and Null Safety

Optional<T> makes the possibility of absence part of the type

<code>Optional&lt;T&gt;</code> forces a caller to explicitly handle the case where a value might be absent, rather than discovering a <code>NullPointerException</code> at runtime. It is not a universal null replacement — using it correctly (return types, not fields or parameters) is the actual skill.

📚 ⚡ Intermediate.
Key focus: Where Optional genuinely helps (return types) versus where it's the wrong tool (fields, parameters).
⏱ 45 min
Required Reading
→
Optional and Null Safety — The Codex

Optional.of/ofNullable/empty, map/filter/orElse chains, and the conventions around where Optional should and shouldn't appear.

STAGE 4

Concurrency and I/O

Reading and writing data, and running work in parallel — including virtual threads, Java's biggest concurrency shift in a decade. Four lessons.

LESSON 20

Virtual Threads

Millions of lightweight threads instead of thousands — finalized in Java 21

Virtual threads, the product of years of work under Project Loom, let you write simple blocking-style code that scales to millions of concurrent threads instead of the low thousands a platform thread's OS-level cost previously allowed. This is arguably the biggest Java concurrency shift since java.util.concurrent itself.

📚 ⚡ Intermediate.
Key focus: Why virtual threads remove the old choice between simple blocking code and high concurrency.
⏱ 1 hours
Required Reading
→
Virtual Threads — The Codex

Platform threads vs virtual threads, Thread.ofVirtual(), structured concurrency, and where virtual threads change idiomatic server code.

LESSON 21

IO and NIO

java.io still works; java.nio.file's Path/Files is what modern code uses

The original stream-based <code>java.io</code> package is still functional, but <code>java.nio.file</code> — with its <code>Path</code> and <code>Files</code> APIs — is what current code actually reaches for: simpler file operations, better error handling, and directory-walking support java.io never had.

📚 ⚡ Intermediate.
Key focus: Why Path/Files replaced java.io.File for nearly everything, and where the old streams API is still needed.
⏱ 1 hours
Required Reading
→
IO and NIO — The Codex

InputStream/OutputStream/Reader/Writer basics, Path and Files, reading/writing files, and directory walking with NIO.2.

LESSON 22

Reflection

java.lang.reflect inspects classes at runtime — slow, powerful, and everywhere

Reflection lets code inspect and manipulate classes, methods, and fields it didn't know about at compile time — the mechanism quietly powering Spring's dependency injection and JUnit's test discovery. It is genuinely slow relative to normal calls, which is why frameworks cache what they discover.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: What reflection actually costs at runtime, and why frameworks like Spring and JUnit depend on it anyway.
⏱ 1 hours
Required Reading
→
Reflection — The Codex

Class objects, inspecting methods/fields/constructors at runtime, invoking reflectively, and reflection's role in frameworks.

LESSON 23

Concurrency, Tied Together

Thread, synchronized, ExecutorService, virtual threads and the Java Memory Model

This lesson is the synthesis for the stage: threads and the classic synchronization primitives, the higher-level <code>ExecutorService</code> abstraction, virtual threads from the previous lesson, <code>CompletableFuture</code> for composing async work, and the Java Memory Model that underpins why any of it is actually safe.

📚 ⚡ Intermediate → 🔥 Expert.
Key focus: Seeing threads, executors, virtual threads and CompletableFuture work together, grounded in the memory model that makes it correct.
⏱ 1.25 hours
Required Reading
→
Concurrency, Tied Together — The Codex

Thread and Runnable, synchronized and volatile, AtomicInteger, ExecutorService, CompletableFuture, and the Java Memory Model.

STAGE 5

Tooling, Modules and Internals

What surrounds the code: build tools, testing, documentation, and what actually happens inside the JVM while your program runs. Seven lessons to close out the course.

LESSON 24

Packages and Modules

Packages organize a JAR; modules (Java 9+) control what it exposes

Packages have organized Java code since 1.0, but the module system introduced in Java 9 goes further: a <code>module-info.java</code> file declares exactly which packages a JAR exposes to the outside world, closing off internal APIs that used to be reachable by accident.

📚 ⚡ Intermediate.
Key focus: The difference between organizing code (packages) and controlling what's visible outside a JAR (modules).
⏱ 45 min
Required Reading
→
Packages and Modules — The Codex

Package declarations and imports, the module system, module-info.java, exports/requires, and encapsulation benefits.

LESSON 25

Build Tools

Maven declares dependencies in XML; Gradle uses a real programming language

Maven and Gradle both manage the same underlying dependency repositories but take opposite philosophies: Maven's declarative XML convention-over-configuration versus Gradle's Groovy/Kotlin DSL that is genuinely programmable. Knowing both is close to a job requirement in real Java work.

📚 ⚡ Intermediate.
Key focus: Maven's declarative convention-over-configuration versus Gradle's programmable build scripts.
⏱ 1 hours
Required Reading
→
Build Tools — The Codex

pom.xml structure, Maven's build lifecycle, Gradle's build.gradle(.kts), dependency management, and choosing between them.

LESSON 26

Testing

JUnit is the standard — now on its 6th major generation, requiring Java 17+

JUnit remains the de facto Java testing standard, and JUnit 6 (current as of late 2025) requires Java 17 as a baseline. This lesson covers writing and organizing real tests, not just the assertion syntax — fixtures, parameterized tests, and mocking with Mockito.

📚 ⚡ Intermediate.
Key focus: Writing real, organized test suites — not just individual assertions — with JUnit 6.
⏱ 1 hours
Required Reading
→
Testing — The Codex

JUnit 6 annotations and assertions, parameterized tests, test lifecycle, and mocking with Mockito.

LESSON 27

Javadoc

A specially formatted comment becomes real, browsable HTML documentation

The <code>javadoc</code> tool generates browsable HTML API documentation directly from specially formatted <code>/** ... */</code> comments in your source — the same mechanism behind every official Java API doc page you have ever read.

📚 🟩 Beginner → ⚡ Intermediate.
Key focus: Writing doc comments that generate genuinely useful API documentation, not just satisfy a linter.
⏱ 30 min
Required Reading
→
Javadoc — The Codex

Javadoc comment syntax, @param/@return/@throws tags, generating HTML docs, and documentation conventions.

LESSON 28

Annotations

@Override does nothing at runtime — metadata read by the compiler and tools

Annotations attach metadata to code that the compiler, build tools, or frameworks read and act on — they are not executable code themselves. <code>@Override</code> is purely a compiler safety check; custom annotations are how frameworks like Spring and JUnit discover what to wire up.

📚 ⚡ Intermediate.
Key focus: The distinction between an annotation (inert metadata) and the tool that reads and acts on it.
⏱ 45 min
Required Reading
→
Annotations — The Codex

Built-in annotations (@Override, @Deprecated, @FunctionalInterface), writing custom annotations, retention policies, and how frameworks use them.

LESSON 29

JVM Internals

The JVM interprets bytecode, then compiles hot paths to native code live

The JVM starts by interpreting bytecode and, as it observes which code paths run most often, compiles those specific hot paths to native machine code via the JIT compiler — a genuinely different execution model from an ahead-of-time compiled language, and the reason long-running Java processes often warm up.

📚 🔥 Expert.
Key focus: Why a Java program often gets faster the longer it runs, and what the JIT compiler is actually doing.
⏱ 1 hours
Required Reading
→
JVM Internals — The Codex

Bytecode and class loading, the interpreter, JIT compilation and hot-path optimization, and HotSpot's tiered compilation.

LESSON 30

Garbage Collection

Several genuinely different collectors — the default has changed more than once

Java has shipped multiple, architecturally different garbage collectors over its history, and which one is the default has changed more than once as tradeoffs between throughput, pause time, and memory overhead shifted. Picking the right one for a workload still genuinely matters in production.

📚 🔥 Expert.
Key focus: Why there is no single best garbage collector, and what tradeoff each major one (G1, ZGC, Parallel) actually makes.
⏱ 1 hours
Required Reading
→
Garbage Collection — The Codex

Generational garbage collection concepts, G1 (the long-standing default), ZGC's low-pause design, and when to choose a non-default collector.

STAGE 6

Concepts That Cross Languages

These pages explain ideas that are not specific to Java — they apply to every language you will ever learn. Read them once and the next language costs you far less effort. They pair well with the lessons above rather than replacing them.

STAGE 7

Build Real Things — 10 Projects

Reading is not enough. These 10 projects — five basic, five medium — are chosen because each one exercises something specific you learned above, and because they are genuinely idiomatic Java rather than generic exercises. Each link below opens the project brief; the Java implementation walkthrough is in progress.

BASIC — 5 PROJECTS
→
Number Guessing Game

Scanner input parsing, loops, and java.util.Random.

→
Temperature Converter

Static methods, a switch expression for the conversion direction, and formatted output.

→
Word Counter

Reading files with NIO's Files API, and HashMap<String, Integer> for a frequency table.

→
To-Do List (CLI)

A record for the task shape, and hand-rolled persistence with the Files API.

→
Password Generator

Enums for character-set options, and SecureRandom for genuinely unpredictable output.

MEDIUM — 5 PROJECTS
→
Web Scraper

java.net.http's HttpClient for real requests, and pattern matching over the parsed response.

→
REST API

com.sun.net.httpserver's built-in HttpServer, sealed types for typed responses, and no external framework.

→
CLI Task Manager

Sealed interfaces for subcommands, and exhaustive switch expressions so a missing case is a compile error.

→
URL Shortener

A thread-safe in-memory store with ConcurrentHashMap, and virtual threads for the HTTP server.

→
Log Analyser

Streams for parsing and aggregating semi-structured lines, and generics for a reusable top-N counter.

STAGE 8

Practice & Experimentation

Ongoing, not a final step. Use these throughout the course — try every snippet you read, and run anything you are unsure about rather than assuming.

Resources
→
Java Playground

Run Java code without installing anything, via the official Java Playground.

→
Java Snippets

Copy-ready idiomatic patterns to keep beside you while you build.

→
Java Reference Hub

All 30 topic pages in one index, for looking things up later.