devflow-kit 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +35 -11
  3. package/dist/cli.js +5 -1
  4. package/dist/commands/ambient.d.ts +18 -0
  5. package/dist/commands/ambient.js +136 -0
  6. package/dist/commands/init.d.ts +2 -0
  7. package/dist/commands/init.js +97 -10
  8. package/dist/commands/memory.d.ts +22 -0
  9. package/dist/commands/memory.js +175 -0
  10. package/dist/commands/uninstall.js +72 -5
  11. package/dist/plugins.js +74 -3
  12. package/dist/utils/post-install.d.ts +12 -0
  13. package/dist/utils/post-install.js +82 -1
  14. package/dist/utils/safe-delete-install.d.ts +7 -0
  15. package/dist/utils/safe-delete-install.js +40 -5
  16. package/package.json +2 -1
  17. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +15 -0
  18. package/plugins/devflow-ambient/.claude-plugin/plugin.json +7 -0
  19. package/plugins/devflow-ambient/README.md +49 -0
  20. package/plugins/devflow-ambient/commands/ambient.md +110 -0
  21. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +89 -0
  22. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +68 -0
  23. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  24. package/plugins/devflow-code-review/.claude-plugin/plugin.json +1 -4
  25. package/plugins/devflow-code-review/agents/reviewer.md +8 -0
  26. package/plugins/devflow-code-review/commands/code-review-teams.md +11 -1
  27. package/plugins/devflow-code-review/commands/code-review.md +12 -2
  28. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +3 -6
  29. package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +10 -6
  30. package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +139 -0
  31. package/plugins/devflow-core-skills/skills/test-driven-development/references/rationalization-prevention.md +111 -0
  32. package/plugins/devflow-debug/.claude-plugin/plugin.json +1 -1
  33. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +15 -0
  34. package/plugins/devflow-go/.claude-plugin/plugin.json +15 -0
  35. package/plugins/devflow-go/skills/go/SKILL.md +187 -0
  36. package/plugins/devflow-go/skills/go/references/concurrency.md +312 -0
  37. package/plugins/devflow-go/skills/go/references/detection.md +129 -0
  38. package/plugins/devflow-go/skills/go/references/patterns.md +232 -0
  39. package/plugins/devflow-go/skills/go/references/violations.md +205 -0
  40. package/plugins/devflow-implement/.claude-plugin/plugin.json +1 -3
  41. package/plugins/devflow-implement/agents/coder.md +11 -6
  42. package/plugins/devflow-java/.claude-plugin/plugin.json +15 -0
  43. package/plugins/devflow-java/skills/java/SKILL.md +183 -0
  44. package/plugins/devflow-java/skills/java/references/detection.md +120 -0
  45. package/plugins/devflow-java/skills/java/references/modern-java.md +270 -0
  46. package/plugins/devflow-java/skills/java/references/patterns.md +235 -0
  47. package/plugins/devflow-java/skills/java/references/violations.md +213 -0
  48. package/plugins/devflow-python/.claude-plugin/plugin.json +15 -0
  49. package/plugins/devflow-python/skills/python/SKILL.md +188 -0
  50. package/plugins/devflow-python/skills/python/references/async.md +220 -0
  51. package/plugins/devflow-python/skills/python/references/detection.md +128 -0
  52. package/plugins/devflow-python/skills/python/references/patterns.md +226 -0
  53. package/plugins/devflow-python/skills/python/references/violations.md +204 -0
  54. package/plugins/devflow-react/.claude-plugin/plugin.json +15 -0
  55. package/plugins/{devflow-core-skills → devflow-react}/skills/react/SKILL.md +1 -1
  56. package/plugins/{devflow-core-skills → devflow-react}/skills/react/references/patterns.md +3 -3
  57. package/plugins/devflow-resolve/.claude-plugin/plugin.json +1 -1
  58. package/plugins/devflow-rust/.claude-plugin/plugin.json +15 -0
  59. package/plugins/devflow-rust/skills/rust/SKILL.md +193 -0
  60. package/plugins/devflow-rust/skills/rust/references/detection.md +131 -0
  61. package/plugins/devflow-rust/skills/rust/references/ownership.md +242 -0
  62. package/plugins/devflow-rust/skills/rust/references/patterns.md +210 -0
  63. package/plugins/devflow-rust/skills/rust/references/violations.md +191 -0
  64. package/plugins/devflow-self-review/.claude-plugin/plugin.json +1 -1
  65. package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
  66. package/plugins/devflow-typescript/.claude-plugin/plugin.json +15 -0
  67. package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/patterns.md +3 -3
  68. package/scripts/hooks/ambient-prompt.sh +48 -0
  69. package/scripts/hooks/background-memory-update.sh +49 -8
  70. package/scripts/hooks/ensure-memory-gitignore.sh +17 -0
  71. package/scripts/hooks/pre-compact-memory.sh +12 -6
  72. package/scripts/hooks/session-start-memory.sh +50 -8
  73. package/scripts/hooks/stop-update-memory.sh +10 -6
  74. package/shared/agents/coder.md +11 -6
  75. package/shared/agents/reviewer.md +8 -0
  76. package/shared/skills/ambient-router/SKILL.md +89 -0
  77. package/shared/skills/ambient-router/references/skill-catalog.md +68 -0
  78. package/shared/skills/docs-framework/SKILL.md +10 -6
  79. package/shared/skills/go/SKILL.md +187 -0
  80. package/shared/skills/go/references/concurrency.md +312 -0
  81. package/shared/skills/go/references/detection.md +129 -0
  82. package/shared/skills/go/references/patterns.md +232 -0
  83. package/shared/skills/go/references/violations.md +205 -0
  84. package/shared/skills/java/SKILL.md +183 -0
  85. package/shared/skills/java/references/detection.md +120 -0
  86. package/shared/skills/java/references/modern-java.md +270 -0
  87. package/shared/skills/java/references/patterns.md +235 -0
  88. package/shared/skills/java/references/violations.md +213 -0
  89. package/shared/skills/python/SKILL.md +188 -0
  90. package/shared/skills/python/references/async.md +220 -0
  91. package/shared/skills/python/references/detection.md +128 -0
  92. package/shared/skills/python/references/patterns.md +226 -0
  93. package/shared/skills/python/references/violations.md +204 -0
  94. package/shared/skills/react/SKILL.md +1 -1
  95. package/shared/skills/react/references/patterns.md +3 -3
  96. package/shared/skills/rust/SKILL.md +193 -0
  97. package/shared/skills/rust/references/detection.md +131 -0
  98. package/shared/skills/rust/references/ownership.md +242 -0
  99. package/shared/skills/rust/references/patterns.md +210 -0
  100. package/shared/skills/rust/references/violations.md +191 -0
  101. package/shared/skills/test-driven-development/SKILL.md +139 -0
  102. package/shared/skills/test-driven-development/references/rationalization-prevention.md +111 -0
  103. package/shared/skills/typescript/references/patterns.md +3 -3
  104. package/src/templates/managed-settings.json +14 -0
  105. package/plugins/devflow-code-review/skills/react/SKILL.md +0 -276
  106. package/plugins/devflow-code-review/skills/react/references/patterns.md +0 -1331
  107. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +0 -229
  108. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +0 -171
  109. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +0 -670
  110. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +0 -419
  111. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +0 -254
  112. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +0 -184
  113. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +0 -511
  114. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +0 -453
  115. package/plugins/devflow-core-skills/skills/react/references/violations.md +0 -565
  116. package/plugins/devflow-implement/skills/accessibility/SKILL.md +0 -229
  117. package/plugins/devflow-implement/skills/accessibility/references/detection.md +0 -171
  118. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +0 -670
  119. package/plugins/devflow-implement/skills/accessibility/references/violations.md +0 -419
  120. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +0 -254
  121. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +0 -184
  122. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +0 -511
  123. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +0 -453
  124. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/SKILL.md +0 -0
  125. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/detection.md +0 -0
  126. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/patterns.md +0 -0
  127. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/violations.md +0 -0
  128. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/SKILL.md +0 -0
  129. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/detection.md +0 -0
  130. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/patterns.md +0 -0
  131. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/violations.md +0 -0
  132. /package/plugins/{devflow-code-review → devflow-react}/skills/react/references/violations.md +0 -0
  133. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/SKILL.md +0 -0
  134. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/violations.md +0 -0
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: java
3
+ description: This skill should be used when the user works with Java files (.java), asks about "records", "sealed classes", "Optional", "streams", "composition over inheritance", or discusses modern Java patterns and API design. Provides patterns for type system usage, error handling, immutability, and concurrency.
4
+ user-invocable: false
5
+ allowed-tools: Read, Grep, Glob
6
+ activation:
7
+ file-patterns:
8
+ - "**/*.java"
9
+ exclude:
10
+ - "**/build/**"
11
+ - "**/target/**"
12
+ ---
13
+
14
+ # Java Patterns
15
+
16
+ Reference for modern Java patterns, type system, and best practices.
17
+
18
+ ## Iron Law
19
+
20
+ > **FAVOR COMPOSITION OVER INHERITANCE**
21
+ >
22
+ > Delegation and interfaces over class hierarchies. Inheritance creates tight coupling,
23
+ > breaks encapsulation, and makes refactoring dangerous. Use interfaces for polymorphism,
24
+ > records for data, and sealed classes for restricted hierarchies. Extend only when the
25
+ > "is-a" relationship is genuinely invariant.
26
+
27
+ ## When This Skill Activates
28
+
29
+ - Working with Java codebases
30
+ - Designing APIs with modern Java features
31
+ - Using records, sealed classes, Optional
32
+ - Implementing concurrent code
33
+ - Structuring Java packages
34
+
35
+ ---
36
+
37
+ ## Type System (Modern Java)
38
+
39
+ ### Records for Data
40
+
41
+ ```java
42
+ // BAD: Mutable POJO with getters/setters
43
+ // GOOD: Immutable record
44
+ public record User(String name, String email, Instant createdAt) {
45
+ public User {
46
+ Objects.requireNonNull(name, "name must not be null");
47
+ Objects.requireNonNull(email, "email must not be null");
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Sealed Classes for Restricted Hierarchies
53
+
54
+ ```java
55
+ public sealed interface Result<T> permits Success, Failure {
56
+ record Success<T>(T value) implements Result<T> {}
57
+ record Failure<T>(String error) implements Result<T> {}
58
+ }
59
+
60
+ // Exhaustive pattern matching (Java 21+)
61
+ switch (result) {
62
+ case Success<User> s -> handleSuccess(s.value());
63
+ case Failure<User> f -> handleError(f.error());
64
+ }
65
+ ```
66
+
67
+ ### Optional for Absent Values
68
+
69
+ ```java
70
+ // BAD: return null;
71
+ // GOOD:
72
+ public Optional<User> findById(String id) {
73
+ return Optional.ofNullable(userMap.get(id));
74
+ }
75
+
76
+ // BAD: if (optional.isPresent()) optional.get()
77
+ // GOOD:
78
+ optional.map(User::name).orElse("Anonymous");
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Error Handling
84
+
85
+ ### Custom Exceptions with Context
86
+
87
+ ```java
88
+ public class EntityNotFoundException extends RuntimeException {
89
+ private final String entityType;
90
+ private final String entityId;
91
+
92
+ public EntityNotFoundException(String entityType, String entityId) {
93
+ super("%s with id %s not found".formatted(entityType, entityId));
94
+ this.entityType = entityType;
95
+ this.entityId = entityId;
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### Try-with-Resources
101
+
102
+ ```java
103
+ // Always use try-with-resources for AutoCloseable
104
+ try (var conn = dataSource.getConnection();
105
+ var stmt = conn.prepareStatement(sql)) {
106
+ stmt.setString(1, id);
107
+ return mapResult(stmt.executeQuery());
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Immutability
114
+
115
+ ```java
116
+ // Prefer unmodifiable collections
117
+ List<String> names = List.of("Alice", "Bob");
118
+ Map<String, Integer> scores = Map.of("Alice", 100, "Bob", 95);
119
+
120
+ // Defensive copies in constructors
121
+ public final class Team {
122
+ private final List<String> members;
123
+ public Team(List<String> members) {
124
+ this.members = List.copyOf(members);
125
+ }
126
+ public List<String> members() { return members; }
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Composition Over Inheritance
133
+
134
+ ```java
135
+ // BAD: class UserService extends BaseService extends AbstractDAO
136
+ // GOOD: compose via constructor injection
137
+ public class UserService {
138
+ private final UserRepository repository;
139
+ private final EventPublisher events;
140
+
141
+ public UserService(UserRepository repository, EventPublisher events) {
142
+ this.repository = repository;
143
+ this.events = events;
144
+ }
145
+ }
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Anti-Patterns
151
+
152
+ | Pattern | Bad | Good |
153
+ |---------|-----|------|
154
+ | Returning null | `return null` | `return Optional.empty()` |
155
+ | Checked exception abuse | `throws Exception` | Specific exceptions or unchecked |
156
+ | Raw types | `List list` | `List<User> list` |
157
+ | Deep inheritance | 4+ level hierarchy | Interfaces + composition |
158
+ | Mutable data objects | `setName()/getName()` | Records or immutable classes |
159
+
160
+ ---
161
+
162
+ ## Extended References
163
+
164
+ For additional patterns and examples:
165
+ - `references/violations.md` - Common Java violations
166
+ - `references/patterns.md` - Extended Java patterns
167
+ - `references/detection.md` - Detection patterns for Java issues
168
+ - `references/modern-java.md` - Modern Java features (17-21+)
169
+
170
+ ---
171
+
172
+ ## Checklist
173
+
174
+ - [ ] Records for pure data types
175
+ - [ ] Sealed interfaces for type hierarchies
176
+ - [ ] Optional instead of null returns
177
+ - [ ] Composition over inheritance
178
+ - [ ] Try-with-resources for all AutoCloseable
179
+ - [ ] Immutable collections (List.of, Map.of)
180
+ - [ ] No raw generic types
181
+ - [ ] Custom exceptions with context
182
+ - [ ] Streams for collection transforms
183
+ - [ ] Constructor injection for dependencies
@@ -0,0 +1,120 @@
1
+ # Detection Patterns for Java Issues
2
+
3
+ Grep and regex patterns for automated detection of Java violations. Reference from main SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Null Returns
8
+
9
+ ```bash
10
+ # Methods returning null instead of Optional
11
+ rg 'return\s+null\s*;' --type java
12
+
13
+ # Nullable method parameters without validation
14
+ rg 'public\s+\w+\s+\w+\((?!.*@NonNull).*\)' --type java
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Raw Types
20
+
21
+ ```bash
22
+ # Raw List, Map, Set, Collection usage
23
+ rg '\b(List|Map|Set|Collection|Iterator|Iterable)\b(?!\s*<)' --type java
24
+
25
+ # Raw Comparable implementation
26
+ rg 'implements\s+Comparable\b(?!\s*<)' --type java
27
+
28
+ # Unsafe casts from Object
29
+ rg '\(\s*(String|Integer|Long|Double)\s*\)\s*\w+\.get' --type java
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Deep Inheritance
35
+
36
+ ```bash
37
+ # Classes extending non-Object/non-interface classes (potential deep hierarchy)
38
+ rg 'class\s+\w+\s+extends\s+(?!Object\b)\w+' --type java
39
+
40
+ # Abstract class chains (look for multiple levels)
41
+ rg 'abstract\s+class\s+\w+\s+extends\s+Abstract' --type java
42
+
43
+ # Count inheritance depth per file
44
+ rg 'extends\s+\w+' --type java --count
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Missing Try-with-Resources
50
+
51
+ ```bash
52
+ # Manual close() calls (should use try-with-resources)
53
+ rg '\.close\(\)\s*;' --type java
54
+
55
+ # InputStream/OutputStream/Connection created outside try-with-resources
56
+ rg 'new\s+(FileInputStream|FileOutputStream|BufferedReader|BufferedWriter|Socket)\(' --type java
57
+
58
+ # getConnection() without try-with-resources context
59
+ rg '\.getConnection\(\)' --type java
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Checked Exception Abuse
65
+
66
+ ```bash
67
+ # Broad throws declarations
68
+ rg 'throws\s+Exception\b' --type java
69
+
70
+ # Empty catch blocks
71
+ rg -U 'catch\s*\([^)]+\)\s*\{\s*\}' --type java --multiline
72
+
73
+ # Catch-and-ignore (catch with only a comment or log)
74
+ rg -U 'catch\s*\([^)]+\)\s*\{\s*(//|/\*|logger\.(debug|trace))' --type java --multiline
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Mutable Data Objects
80
+
81
+ ```bash
82
+ # Setter methods (JavaBean anti-pattern for data objects)
83
+ rg 'public\s+void\s+set[A-Z]\w*\(' --type java
84
+
85
+ # Mutable collections returned from getters
86
+ rg 'return\s+(this\.)?(list|map|set|collection)\s*;' --type java -i
87
+
88
+ # Missing defensive copies in constructors
89
+ rg 'this\.\w+\s*=\s*\w+\s*;' --type java
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Concurrency Issues
95
+
96
+ ```bash
97
+ # HashMap in concurrent context (should be ConcurrentHashMap)
98
+ rg 'new\s+HashMap\b' --type java
99
+
100
+ # Missing volatile on shared fields
101
+ rg 'private\s+(?!volatile\s)(?!final\s)\w+\s+\w+\s*=' --type java
102
+
103
+ # Synchronized on non-private lock object
104
+ rg 'synchronized\s*\(\s*this\s*\)' --type java
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Streams Anti-Patterns
110
+
111
+ ```bash
112
+ # Stream.forEach with side effects (should use for-loop or collect)
113
+ rg '\.stream\(\).*\.forEach\(' --type java
114
+
115
+ # Nested streams (performance concern)
116
+ rg '\.stream\(\).*\.stream\(\)' --type java
117
+
118
+ # collect(Collectors.toList()) instead of .toList() (Java 16+)
119
+ rg 'collect\(Collectors\.toList\(\)\)' --type java
120
+ ```
@@ -0,0 +1,270 @@
1
+ # Modern Java Features (17-21+)
2
+
3
+ Deep-dive on modern Java language features. Reference from main SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Records (Java 16+)
8
+
9
+ ### Basic Record
10
+
11
+ ```java
12
+ // Immutable data carrier with auto-generated equals, hashCode, toString
13
+ public record Point(double x, double y) {}
14
+
15
+ // Usage
16
+ var p = new Point(3.0, 4.0);
17
+ double x = p.x(); // Accessor method, not getX()
18
+ ```
19
+
20
+ ### Compact Constructor (Validation)
21
+
22
+ ```java
23
+ public record Email(String value) {
24
+ public Email {
25
+ Objects.requireNonNull(value, "email must not be null");
26
+ if (!value.contains("@")) {
27
+ throw new IllegalArgumentException("Invalid email: " + value);
28
+ }
29
+ value = value.toLowerCase().strip(); // Reassign before final assignment
30
+ }
31
+ }
32
+ ```
33
+
34
+ ### Record with Custom Methods
35
+
36
+ ```java
37
+ public record Range(int start, int end) {
38
+ public Range {
39
+ if (start > end) throw new IllegalArgumentException("start must be <= end");
40
+ }
41
+
42
+ public int length() { return end - start; }
43
+ public boolean contains(int value) { return value >= start && value <= end; }
44
+ public Range overlap(Range other) {
45
+ int newStart = Math.max(start, other.start);
46
+ int newEnd = Math.min(end, other.end);
47
+ return newStart <= newEnd ? new Range(newStart, newEnd) : null;
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Records as Local Classes
53
+
54
+ ```java
55
+ public List<String> processOrders(List<Order> orders) {
56
+ // Local record for intermediate computation
57
+ record OrderTotal(String orderId, Money total) {}
58
+
59
+ return orders.stream()
60
+ .map(o -> new OrderTotal(o.id(), o.calculateTotal()))
61
+ .filter(ot -> ot.total().isGreaterThan(Money.of(100)))
62
+ .map(OrderTotal::orderId)
63
+ .toList();
64
+ }
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Sealed Classes (Java 17+)
70
+
71
+ ### Sealed Interface
72
+
73
+ ```java
74
+ public sealed interface Shape permits Circle, Rectangle, Triangle {
75
+ double area();
76
+ }
77
+
78
+ public record Circle(double radius) implements Shape {
79
+ public double area() { return Math.PI * radius * radius; }
80
+ }
81
+
82
+ public record Rectangle(double width, double height) implements Shape {
83
+ public double area() { return width * height; }
84
+ }
85
+
86
+ public record Triangle(double base, double height) implements Shape {
87
+ public double area() { return 0.5 * base * height; }
88
+ }
89
+ ```
90
+
91
+ ### Sealed Class with Abstract Methods
92
+
93
+ ```java
94
+ public sealed abstract class Payment permits CreditCard, BankTransfer, Crypto {
95
+ abstract Money amount();
96
+ abstract String reference();
97
+ }
98
+
99
+ public final class CreditCard extends Payment {
100
+ private final String cardLast4;
101
+ private final Money amount;
102
+ // ...
103
+ }
104
+
105
+ public final class BankTransfer extends Payment { /* ... */ }
106
+ public final class Crypto extends Payment { /* ... */ }
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Pattern Matching (Java 21+)
112
+
113
+ ### Switch with Patterns
114
+
115
+ ```java
116
+ // Exhaustive pattern matching on sealed types
117
+ public String describe(Shape shape) {
118
+ return switch (shape) {
119
+ case Circle c -> "Circle with radius %.2f".formatted(c.radius());
120
+ case Rectangle r -> "Rectangle %s x %s".formatted(r.width(), r.height());
121
+ case Triangle t -> "Triangle with base %.2f".formatted(t.base());
122
+ };
123
+ }
124
+ ```
125
+
126
+ ### Guarded Patterns
127
+
128
+ ```java
129
+ public String classifyTemperature(Object obj) {
130
+ return switch (obj) {
131
+ case Integer i when i < 0 -> "Freezing";
132
+ case Integer i when i < 15 -> "Cold";
133
+ case Integer i when i < 25 -> "Comfortable";
134
+ case Integer i -> "Hot";
135
+ case Double d when d < 0.0 -> "Freezing";
136
+ case Double d -> "Warm-ish (%.1f)".formatted(d);
137
+ case String s -> "Not a temperature: " + s;
138
+ case null -> "No reading";
139
+ default -> "Unknown type";
140
+ };
141
+ }
142
+ ```
143
+
144
+ ### Record Patterns (Destructuring)
145
+
146
+ ```java
147
+ // Nested destructuring
148
+ record Address(String city, String country) {}
149
+ record Person(String name, Address address) {}
150
+
151
+ public String greet(Object obj) {
152
+ return switch (obj) {
153
+ case Person(var name, Address(var city, _)) ->
154
+ "Hello %s from %s".formatted(name, city);
155
+ default -> "Hello stranger";
156
+ };
157
+ }
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Text Blocks (Java 15+)
163
+
164
+ ```java
165
+ // Multi-line strings with proper indentation
166
+ String json = """
167
+ {
168
+ "name": "%s",
169
+ "email": "%s",
170
+ "active": true
171
+ }
172
+ """.formatted(user.name(), user.email());
173
+
174
+ String sql = """
175
+ SELECT u.id, u.name, u.email
176
+ FROM users u
177
+ JOIN orders o ON o.user_id = u.id
178
+ WHERE u.active = true
179
+ AND o.created_at > ?
180
+ ORDER BY u.name
181
+ """;
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Virtual Threads (Java 21+)
187
+
188
+ ### Basic Virtual Thread
189
+
190
+ ```java
191
+ // Lightweight thread - does not pin platform thread during I/O
192
+ Thread.startVirtualThread(() -> {
193
+ var result = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
194
+ process(result.body());
195
+ });
196
+ ```
197
+
198
+ ### Structured Concurrency (Preview)
199
+
200
+ ```java
201
+ // All subtasks complete or cancel together
202
+ try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
203
+ Subtask<User> userTask = scope.fork(() -> fetchUser(userId));
204
+ Subtask<List<Order>> ordersTask = scope.fork(() -> fetchOrders(userId));
205
+
206
+ scope.join().throwIfFailed();
207
+
208
+ return new UserDashboard(userTask.get(), ordersTask.get());
209
+ }
210
+ ```
211
+
212
+ ### ExecutorService with Virtual Threads
213
+
214
+ ```java
215
+ // Process thousands of concurrent I/O tasks
216
+ try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
217
+ List<Future<Response>> futures = urls.stream()
218
+ .map(url -> executor.submit(() -> httpClient.send(
219
+ HttpRequest.newBuilder(URI.create(url)).build(),
220
+ HttpResponse.BodyHandlers.ofString()
221
+ )))
222
+ .toList();
223
+
224
+ List<Response> responses = futures.stream()
225
+ .map(f -> {
226
+ try { return f.get(); }
227
+ catch (Exception e) { throw new RuntimeException(e); }
228
+ })
229
+ .toList();
230
+ }
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Other Modern Features
236
+
237
+ ### Enhanced instanceof (Java 16+)
238
+
239
+ ```java
240
+ // Pattern variable binding eliminates explicit cast
241
+ if (obj instanceof String s && s.length() > 5) {
242
+ System.out.println(s.toUpperCase());
243
+ }
244
+
245
+ // Works with negation
246
+ if (!(obj instanceof String s)) {
247
+ throw new IllegalArgumentException("Expected String");
248
+ }
249
+ // s is in scope here
250
+ process(s);
251
+ ```
252
+
253
+ ### Helpful NullPointerExceptions (Java 14+)
254
+
255
+ ```java
256
+ // JVM now tells you exactly which reference was null:
257
+ // java.lang.NullPointerException: Cannot invoke "String.length()"
258
+ // because the return value of "User.name()" is null
259
+ // Enable with: -XX:+ShowCodeDetailsInExceptionMessages (default since Java 17)
260
+ ```
261
+
262
+ ### Stream Gatherers (Java 22+ Preview)
263
+
264
+ ```java
265
+ // Custom intermediate stream operations
266
+ var windowedAverages = temperatures.stream()
267
+ .gather(Gatherers.windowSliding(5))
268
+ .map(window -> window.stream().mapToDouble(d -> d).average().orElse(0))
269
+ .toList();
270
+ ```