Checkpoint: Modern Java
This checkpoint consolidates the modern Java unit — var , text blocks, switch expressions, pattern matching, sealed types, record patterns, method references, and functional interfaces — into one build challenge you complete end to end.
Learn Checkpoint: Modern Java in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
How This Checkpoint Works
First skim the recap, then tackle the multi-step build challenge on your own. A full, compiled solution is hidden under "Show solution" — try before you peek. Finish with the written checkpoint quiz and the timed quiz to confirm it all stuck.
Unit Recap — Eight Features
Quick Recap in Code
A single program touching several of the features at once: var , a Predicate + method reference, a switch expression, a text block, and an instanceof pattern.
🏗️ Build Challenge — A Shape Report
Model a small sealed hierarchy of shape records , then process it with a pattern switch that deconstructs each record — wiring in var , a text block, a guard, method references, and streams. Follow the five steps in the starter, aim for the exact expected output, and only then open the solution.
✅ Full Solution
Attempt the challenge first. When you're ready, expand the compiled, runnable solution below.
Notice the design: a sealed Shape of three records; describe and area are both exhaustive pattern switches with no default ; the when w == h guard splits squares from rectangles; and main uses var , a text block, Main::describe as a method reference, and a stream sum .
📝 Checkpoint Quiz
Answer: Shape is sealed and permits exactly Circle , Rectangle , and Triangle . With an arm for each, the compiler proves the switch is exhaustive, so a default is unnecessary — and omitting it means adding a fourth shape would turn the switch into a compile error until you handle it.
Answer: It is a record pattern . It matches a Circle and immediately deconstructs it, binding the component to r — so you use r directly instead of calling c.radius() .
Answer: A switch tries arms top to bottom and takes the first match. The plain case Rectangle(double w, double h) matches every rectangle, so the when w == h arm must precede it — otherwise the guarded arm would be unreachable, which is a compile error.
Answer: var shapes = List.of(...) is fine — a local with an initializer. var could not appear on the record components, the method parameters ( Shape s ), or the return types of area / describe , because those are part of the API contract.
Answer: Type::staticMethod — describe is a static method of Main . In .map(Main::describe) it stands in for s -> Main.describe(s) .
Answer: "Circle: area=%.2f".formatted(value) is the instance form of String.format ; %.2f inserts the area rounded to two decimals. There is no string interpolation in Java, so placeholders plus .formatted are the idiom.
Watch Out For
- ❌ Putting the plain Rectangle arm before the guarded one. Unreachable code. Fix: guard first.
- ❌ Adding a default to the sealed switch. Hides the safety net. Fix: rely on exhaustiveness.
- ❌ Using var on a record component or parameter. Illegal. Fix: declare the type.
- ❌ Wrong record-pattern arity. Each component needs a sub-pattern. Fix: Rectangle(double w, double h) .
- ❌ Expecting $ { area } interpolation in the text. None exists. Fix: %.2f + .formatted .
- ❌ Compiling on Java 20 or earlier. Record patterns need 21. Fix: use Java 21+.
Carry These Forward
- 💡 sealed + records + switch is the modern recipe for modelling and processing a closed set of cases safely.
- 💡 Let the compiler be your checklist — skip default on closed hierarchies so new cases surface as errors.
- 💡 Favour small functional pieces — predicates, mappers, and method references compose into readable pipelines.
- 💡 Reach for var and text blocks to cut boilerplate, but keep explicit types where they document intent.
📋 Quick Reference — Modern Java at a Glance
Feature
Syntax
Since
var
var x = expr;
Java 10
Text block
"""\n...\n"""
Java 15
Switch expression
var v = switch (k) {...} ;
Java 14
yield
case X -> { yield v; }
instanceof pattern
o instanceof String s
Java 16
sealed / permits
sealed ... permits A, B
Java 17
switch patterns
case Integer i -> ...
Java 21
Guard
case X x when cond -> ...
Record pattern
case Point(int x, int y)
Method reference
Type::method, Type::new
Java 8
Functional interface
Function, Predicate, ...
.formatted()
"%s".formatted(x)
📚 Resources / Keep Learning
- 📘 Oracle: Java Language Changes — every feature, version by version.
- 📗 dev.java: Learn Java — the official, up-to-date tutorial hub.
- 📙 Oracle: Pattern Matching — instanceof, switch, and record patterns in depth.
❓ Frequently Asked Questions
🎉 Checkpoint Cleared!
You combined var , text blocks, switch expressions, pattern matching, sealed types, record patterns, method references, and functional interfaces into a single working program — the heart of modern, data-oriented Java.
Next up: Stream Collectors Deep Dive — grouping, partitioning, joining, and summarising with the Collectors toolkit.
Practice quiz
Where can var be used?
- Fields and parameters
- Return types
- Only local variables with an initializer
- Anywhere
Answer: Only local variables with an initializer. var is for local variables with an initializer — never fields, parameters, or return types.
How do you insert values into a text block?
- .formatted(...) or String.format
- ${var} interpolation
- + only
- You can't
Answer: .formatted(...) or String.format. Java has no interpolation; use %s/%d placeholders with .formatted(...).
What does a switch expression produce?
- Nothing
- Only side effects
- A boolean
- A value you can assign or return
Answer: A value you can assign or return. A switch expression evaluates to a value, using arrow arms and yield for blocks.
What does if (o instanceof String s) give you?
- A boolean only
- A test plus a ready-to-use String s
- A cast exception
- A new string
Answer: A test plus a ready-to-use String s. Pattern matching for instanceof tests the type and binds s, no explicit cast.
Why can a switch over a sealed type omit default?
- permits lists all subtypes, so the compiler proves exhaustiveness
- Switches never need default
- Sealed disables default
- It uses reflection
Answer: permits lists all subtypes, so the compiler proves exhaustiveness. Because the set of subtypes is closed and known, an arm per subtype is exhaustive.
What does case Point(int x, int y) do?
- Creates a Point
- Compares points
- Matches a Point and deconstructs it into x and y
- Calls a method
Answer: Matches a Point and deconstructs it into x and y. A record pattern matches and binds the components in one step.
Which is a constructor reference?
- Integer::parseInt
- ArrayList::new
- System.out::println
- String::length
Answer: ArrayList::new. Type::new is a constructor reference; the others are static, bound, and unbound instance references.
Which functional interface takes a T and returns a boolean?
- Function<T,R>
- Consumer<T>
- Supplier<T>
- Predicate<T>
Answer: Predicate<T>. Predicate<T>.test returns boolean.
f.andThen(g).apply(x) computes:
- f(g(x))
- g(f(x))
- f(x) and g(x)
- Nothing
Answer: g(f(x)). andThen runs f first, then feeds the result to g: g(f(x)).
Which combination enables data-oriented programming in modern Java?
- var + loops
- threads + locks
- sealed types + records + pattern matching
- reflection + generics
Answer: sealed types + records + pattern matching. Sealed types model a closed set, records hold the data, and patterns process them exhaustively.
Continue this course
- Previous: Built-in Functional Interfaces
- Next: Stream Collectors Deep Dive