✓ Recommended
Java 21+ Modern Patterns
Modern Java patterns including records, sealed classes, pattern matching, virtual threads, and structured concurrency.
CLAUDE.md
# Java 21+ Modern Patterns
You are an expert in modern Java (21+) with deep knowledge of recent language features and best practices.
Records (Data Carriers):
- Use record for immutable data classes: record Point(int x, int y) {}
- Records auto-generate: constructor, getters, equals(), hashCode(), toString()
- Use compact constructors for validation: record Age(int value) { Age { if (value < 0) throw new IllegalArgumentException(); } }
- Records are final and implicitly implement Serializable-friendly patterns
- Prefer records over Lombok @Data for DTOs, API responses, and value objects
Sealed Classes & Interfaces:
- Use sealed to define a closed set of subtypes: sealed interface Shape permits Circle, Rectangle, Triangle {}
- Combine with records for algebraic data types: record Circle(double radius) implements Shape {}
- The compiler enforces exhaustive pattern matching on sealed hierarchies
- Use for domain modeling where the set of variants is known and fixed
Pattern Matching:
- instanceof pattern: if (obj instanceof String s) { use(s); } — no cast needed
- Switch pattern matching: switch (shape) { case Circle c -> area(c); case Rectangle r -> area(r); }
- Guarded patterns: case Circle c when c.radius() > 10 -> "large circle"
- Record patterns: case Point(var x, var y) -> x + y (destructuring)
- Null handling in switch: case null -> "missing" (explicit null branch)
Virtual Threads (Project Loom):
- Use Thread.ofVirtual().start(() -> task()) for lightweight concurrency
- Virtual threads are cheap (millions possible) — don't pool them
- Use Executors.newVirtualThreadPerTaskExecutor() for I/O-bound workloads
- Avoid synchronized blocks in virtual thread code (use ReentrantLock)
- Virtual threads are ideal for HTTP servers, database calls, file I/O
Structured Concurrency (Preview):
- Use StructuredTaskScope for managing concurrent subtasks with clear ownership
- ShutdownOnFailure: cancel all tasks if any one fails
- ShutdownOnSuccess: cancel remaining tasks when first succeeds
- Ensures no orphaned threads — all subtasks complete before scope closes
Modern Collections & Streams:
- Use List.of(), Map.of(), Set.of() for immutable collections
- Use Stream.toList() instead of .collect(Collectors.toList())
- Use mapMulti() for conditional flat-mapping
- Use teeing() collector for computing two results in one pass
- Text blocks: multi-line strings with triple quotes and proper indentation
Add to your project root CLAUDE.md file, or append to an existing one.