0
# Advanced Features
1
2
Specialized features including modifiable companions, collection ordering, inclusion patterns, enclosing type organization, and extended generation capabilities for complex scenarios.
3
4
## Capabilities
5
6
### Modifiable Companions
7
8
Generate mutable companion classes that can be converted to and from immutable instances.
9
10
```java { .api }
11
/**
12
* Generate modifiable implementation of abstract value class.
13
* Provides over-flexible builder or partially built representation.
14
* Generated with "Modifiable" prefix by default.
15
*/
16
@interface Value.Modifiable { }
17
```
18
19
**Usage Examples:**
20
21
```java
22
@Value.Immutable
23
@Value.Modifiable
24
public interface Person {
25
String name();
26
int age();
27
List<String> hobbies();
28
Optional<String> email();
29
}
30
31
// Both immutable and modifiable implementations generated
32
// ImmutablePerson - immutable implementation
33
// ModifiablePerson - mutable implementation
34
35
// Create modifiable instance
36
ModifiablePerson modifiable = ModifiablePerson.create()
37
.setName("Alice")
38
.setAge(25)
39
.addHobbies("reading")
40
.setEmail("alice@example.com");
41
42
// Modify values
43
modifiable.setAge(26);
44
modifiable.addHobbies("swimming", "hiking");
45
modifiable.getHobbies().add("cooking"); // Direct collection access
46
47
// Convert to immutable
48
Person immutable = modifiable.toImmutable();
49
50
// Convert back to modifiable for further changes
51
ModifiablePerson anotherModifiable = ModifiablePerson.copyOf(immutable);
52
53
// Modifiable from builder pattern
54
ModifiablePerson fromBuilder = ModifiablePerson.create()
55
.from(immutable) // Initialize from existing instance
56
.setAge(27);
57
```
58
59
### Collection Ordering
60
61
Control the ordering behavior of generated collection implementations.
62
63
```java { .api }
64
/**
65
* Specify natural ordering for implemented SortedSet, NavigableSet,
66
* SortedMap, or NavigableMap. Elements must implement Comparable.
67
*/
68
@interface Value.NaturalOrder { }
69
70
/**
71
* Specify reversed natural ordering for sorted collections.
72
* Elements must implement Comparable.
73
*/
74
@interface Value.ReverseOrder { }
75
```
76
77
**Usage Examples:**
78
79
```java
80
@Value.Immutable
81
public interface SortedData {
82
// Natural ordering - ascending
83
@Value.NaturalOrder
84
SortedSet<String> names();
85
86
// Reverse ordering - descending
87
@Value.ReverseOrder
88
SortedSet<Integer> scores();
89
90
// Natural ordering for map
91
@Value.NaturalOrder
92
SortedMap<String, Integer> rankings();
93
94
// Regular collections (no special ordering)
95
List<String> tags();
96
Set<String> categories();
97
}
98
99
// Usage with automatic ordering
100
SortedData data = ImmutableSortedData.builder()
101
.addNames("Charlie", "Alice", "Bob") // Stored as: Alice, Bob, Charlie
102
.addScores(85, 92, 78) // Stored as: 92, 85, 78 (descending)
103
.putRankings("Alice", 1)
104
.putRankings("Bob", 2) // Stored by key order: Alice, Bob
105
.addTags("urgent", "review", "feature") // Insertion order preserved
106
.build();
107
108
// Accessing ordered collections
109
SortedSet<String> orderedNames = data.names(); // [Alice, Bob, Charlie]
110
SortedSet<Integer> orderedScores = data.scores(); // [92, 85, 78]
111
```
112
113
### Inclusion Patterns
114
115
Include external types in generation without modifying their source code.
116
117
```java { .api }
118
/**
119
* Includes specified abstract value types into generation processing.
120
* Used to generate immutable implementations of classes from different
121
* packages where source code cannot be changed.
122
*/
123
@interface Value.Include {
124
Class<?>[] value();
125
}
126
```
127
128
**Usage Examples:**
129
130
```java
131
// External interface that cannot be modified
132
package com.external.library;
133
public interface ExternalConfig {
134
String getHost();
135
int getPort();
136
boolean isSecure();
137
}
138
139
// Include external types for generation
140
package com.myapp.config;
141
142
@Value.Include({
143
com.external.library.ExternalConfig.class,
144
com.external.library.DatabaseSettings.class
145
})
146
@Value.Immutable
147
public interface MyConfig extends ExternalConfig {
148
@Override
149
default String getHost() { return "localhost"; }
150
151
@Override
152
default int getPort() { return 8080; }
153
154
@Override
155
default boolean isSecure() { return false; }
156
157
// Additional attributes specific to MyConfig
158
String applicationName();
159
List<String> allowedOrigins();
160
}
161
162
// Generated: ImmutableMyConfig implementing both interfaces
163
MyConfig config = ImmutableMyConfig.builder()
164
.host("production.example.com")
165
.port(443)
166
.secure(true)
167
.applicationName("MyApp")
168
.addAllowedOrigins("https://app.example.com", "https://admin.example.com")
169
.build();
170
171
// Works with external interface type
172
ExternalConfig external = config; // Upcasting works
173
String host = external.getHost();
174
```
175
176
### Enclosing Type Organization
177
178
Organize generated classes under umbrella top-level classes for better namespace management.
179
180
```java { .api }
181
/**
182
* Applied to top level class containing nested abstract value types
183
* to provide namespacing. Generated implementation classes will be
184
* nested under "Immutable" prefixed umbrella class.
185
*/
186
@interface Value.Enclosing { }
187
```
188
189
**Usage Examples:**
190
191
```java
192
@Value.Enclosing
193
public class GraphPrimitives {
194
195
@Value.Immutable
196
public interface Vertex {
197
String id();
198
double x();
199
double y();
200
@Value.Default
201
default String label() { return id(); }
202
}
203
204
@Value.Immutable
205
public interface Edge {
206
String id();
207
Vertex source();
208
Vertex target();
209
@Value.Default
210
default double weight() { return 1.0; }
211
}
212
213
@Value.Immutable
214
public interface Graph {
215
Set<Vertex> vertices();
216
Set<Edge> edges();
217
218
@Value.Check
219
protected void validateGraph() {
220
// Ensure all edge endpoints exist in vertex set
221
Set<String> vertexIds = vertices().stream()
222
.map(Vertex::id)
223
.collect(Collectors.toSet());
224
225
for (Edge edge : edges()) {
226
if (!vertexIds.contains(edge.source().id()) ||
227
!vertexIds.contains(edge.target().id())) {
228
throw new IllegalStateException(
229
"Edge " + edge.id() + " references non-existent vertex"
230
);
231
}
232
}
233
}
234
}
235
}
236
237
// Generated umbrella class: ImmutableGraphPrimitives
238
// Generated nested classes:
239
// - ImmutableGraphPrimitives.Vertex
240
// - ImmutableGraphPrimitives.Edge
241
// - ImmutableGraphPrimitives.Graph
242
243
// Usage with clean imports
244
import static com.example.ImmutableGraphPrimitives.*;
245
246
// Simple class names without "Immutable" prefix
247
Vertex v1 = Vertex.builder().id("v1").x(0).y(0).build();
248
Vertex v2 = Vertex.builder().id("v2").x(1).y(1).build();
249
250
Edge edge = Edge.builder()
251
.id("e1")
252
.source(v1)
253
.target(v2)
254
.weight(2.5)
255
.build();
256
257
Graph graph = Graph.builder()
258
.addVertices(v1, v2)
259
.addEdges(edge)
260
.build();
261
```
262
263
### Advanced Builder Features
264
265
Enhanced builder functionality for complex construction scenarios.
266
267
```java { .api }
268
/**
269
* Style configuration for advanced builder features
270
*/
271
@interface Value.Style {
272
/**
273
* Generate attribute builder methods for discoverable nested builders.
274
* Enables fluent construction of nested immutable objects.
275
*/
276
boolean attributeBuilderDetection() default false;
277
278
/**
279
* Patterns for detecting builder methods on attribute types.
280
*/
281
String[] attributeBuilder() default {"Builder", "*Builder", "builder", "new"};
282
283
/**
284
* Generate toBuilder() method on immutable instances.
285
*/
286
String toBuilder() default "";
287
}
288
```
289
290
**Usage Examples:**
291
292
```java
293
// Nested builders with attribute builder detection
294
@Value.Style(
295
attributeBuilderDetection = true,
296
toBuilder = "toBuilder"
297
)
298
@Value.Immutable
299
public interface Order {
300
Customer customer();
301
List<OrderItem> items();
302
Address shippingAddress();
303
}
304
305
@Value.Immutable
306
public interface Customer {
307
String name();
308
String email();
309
310
static Builder builder() { return ImmutableCustomer.builder(); }
311
}
312
313
@Value.Immutable
314
public interface OrderItem {
315
String productId();
316
int quantity();
317
BigDecimal price();
318
319
static Builder builder() { return ImmutableOrderItem.builder(); }
320
}
321
322
// Enhanced builder with nested builder methods
323
Order order = ImmutableOrder.builder()
324
.customerBuilder() // Returns Customer.Builder
325
.name("John Doe")
326
.email("john@example.com")
327
.addItemsBuilder() // Returns OrderItem.Builder for collection
328
.productId("LAPTOP-001")
329
.quantity(1)
330
.price(new BigDecimal("999.99"))
331
.addItemsBuilder() // Another item builder
332
.productId("MOUSE-001")
333
.quantity(2)
334
.price(new BigDecimal("25.99"))
335
.shippingAddressBuilder() // Returns Address.Builder
336
.street("123 Main St")
337
.city("Springfield")
338
.zipCode("12345")
339
.build();
340
341
// toBuilder() for creating modified copies
342
Order.Builder orderBuilder = order.toBuilder();
343
Order updatedOrder = orderBuilder
344
.customerBuilder()
345
.email("john.doe@example.com") // Update customer email
346
.build();
347
```
348
349
### Serialization Support
350
351
Built-in support for various serialization frameworks and custom serialization patterns.
352
353
**Usage Examples:**
354
355
```java
356
// Jackson JSON serialization
357
@Value.Immutable
358
@JsonSerialize(as = ImmutableUser.class)
359
@JsonDeserialize(as = ImmutableUser.class)
360
public interface User {
361
@JsonProperty("user_name")
362
String name();
363
364
@JsonProperty("user_age")
365
int age();
366
367
@JsonIgnore
368
@Value.Auxiliary
369
long internalId();
370
}
371
372
// Java serialization
373
@Value.Immutable
374
public interface SerializableData implements Serializable {
375
String data();
376
int version();
377
378
@Value.Auxiliary // Excluded from serialization
379
transient long timestamp();
380
}
381
382
// Custom serialization with Style
383
@Value.Style(
384
forceJacksonPropertyNames = false, // Use custom naming strategy
385
forceJacksonIgnoreFields = true // Add @JsonIgnore to fields
386
)
387
@Value.Immutable
388
public interface CustomSerialization {
389
String publicData();
390
391
@Value.Redacted
392
String sensitiveData();
393
}
394
```