Modern Java
On this page 8 topics
Overview
Topics
- Release cadence
- LTS versions
- records
- sealed classes
- switch expressions
- text blocks
- pattern matching
Learn first
87 min of reading · 4 h of practice (estimate)
Learning outcomes
- Explain Java's six-month release cadence, what LTS means, and how to choose a version for production.
- Replace boilerplate data classes with records, including compact constructors that validate.
- Model closed hierarchies with sealed interfaces and handle them exhaustively with pattern-matching
switch. - Use text blocks,
instanceofpatterns, and record patterns where they improve readability.
Lessons
- 01Java's release model and LTS versions10 min read
- 02Records11 min read
- 03Sealed classes and interfaces11 min read
- 04Switch expressions and pattern matching11 min read
- 05Record patterns11 min read
- 06Text blocks and other small wins11 min read
- 07What changed since the last LTS (updated per release)11 min read
- 08Demo: modernizing a legacy Java class step by step11 min read
Lab and exercises
Lab
JNR-001-LAB1 · Shop Core v1
Outcomes: 2–4 · Time: ~2.5 h Model Product, Money, and CartLine as records with validation in compact constructors. Model Discount as a sealed hierarchy (percentage, fixed amount, buy-X-get-Y) and price a cart line with an exhaustive switch. Acceptance: no setters anywhere; adding a new discount type causes a compile error until the switch handles it; no default branch.
Exercises (assessment: refactor a legacy POJO-heavy module and justify each change, plus seven exercises)
| ID | Outcome | Task |
|---|---|---|
| JNR-001-EX01 | 1 | Explain in three sentences the six-month cadence, what LTS means, and which version you would choose for a new production service and why. |
| JNR-001-EX02 | 2 | Rewrite a Customer class (name, email, getters, setters, equals, hashCode, toString) as a record. Reject a blank name. |
| JNR-001-EX03 | 2 | A record has a List<String> tags component. Show how a caller can break it and fix it. |
| JNR-001-EX04 | 3 | Declare a sealed interface PaymentMethod with Card, Cash, Voucher. Write a switch returning a fee for each. |
| JNR-001-EX05 | 3 | Add Transfer to PaymentMethod without touching the switch. What happens? Why is default harmful here? |
| JNR-001-EX06 | 4 | Rewrite a chain of if (o instanceof X) { X x = (X) o; ... } with pattern matching, and a concatenated JSON string with a text block. |
| JNR-001-EX07 | 4 | Use a record pattern to print Money(cents, currency) from an Object using instanceof. |
Show solutions
- EX01 Releases every six months (March, September); LTS gets years of support; pick the current LTS, because it is patched for a long time (verify the version).
- EX02
record Customer(String name, String email) { Customer { if (name == null || name.isBlank()) throw new IllegalArgumentException("name"); } }. - EX03 The caller keeps the original list and changes it. Fix:
tags = List.copyOf(tags);in the compact constructor. - EX04
sealed interface PaymentMethod permits Card, Cash, Voucher {}(records);switch (m) { case Card c -> ...; case Cash c -> ...; case Voucher v -> ...; }. - EX05 The code fails to compile: the switch is not exhaustive. With
default, it would compile and silently use the wrong fee. - EX06
if (o instanceof Product p) { ... p.name() ... }; a text block with three quotes and no escaped quotes. - EX07
if (o instanceof Money(long cents, String currency)) { System.out.println(cents + " " + currency); }. - Outcome 1 is also covered by quiz Q01–Q03; the lab covers outcomes 2–4.
Quiz
Outcomes: O1 release model and LTS · O2 records · O3 sealed types and switch · O4 patterns, text blocks.
A self-check for you: nothing is graded, saved or sent anywhere. Choose an answer, then check it. You can try again as often as you like.
Practical part
Seven exercises JNR-001-EX01 to EX07, the legacy-refactoring task, and the lab. Pass: at least 8 of 10 quiz answers, six exercises correct, and a lab that fails to compile when a discount type is unhandled.
Common mistakes
Records with mutable components (lists not copied); default branches that defeat exhaustiveness; using preview features in production code.
Assessment
Refactor a legacy POJO-heavy module to modern Java and justify each change.
Career relevance
Modern codebases and interviews expect these features; sealed types reappear in event modeling (SRB-002).