0
# Serialization
1
2
The @SerializableAutoValue annotation generates serializable implementations for AutoValue classes that contain non-serializable fields like Optional, ImmutableList, or other modern Java types.
3
4
## Basic Serializable AutoValue
5
6
```java { .api }
7
@SerializableAutoValue
8
@AutoValue
9
public abstract class Person implements Serializable {
10
public abstract String name();
11
public abstract Optional<String> email();
12
public abstract ImmutableList<String> hobbies();
13
14
public static Person create(String name, Optional<String> email, ImmutableList<String> hobbies) {
15
return new AutoValue_Person(name, email, hobbies);
16
}
17
}
18
```
19
20
The generated code automatically handles serialization of:
21
- `Optional<T>` fields
22
- `ImmutableList<T>`, `ImmutableSet<T>`, `ImmutableMap<K,V>`
23
- Other common non-serializable types
24
25
## Usage Example
26
27
```java
28
Person person = Person.create(
29
"Alice",
30
Optional.of("alice@example.com"),
31
ImmutableList.of("reading", "coding", "hiking"));
32
33
// Serialize to bytes
34
ByteArrayOutputStream baos = new ByteArrayOutputStream();
35
ObjectOutputStream oos = new ObjectOutputStream(baos);
36
oos.writeObject(person);
37
byte[] serialized = baos.toByteArray();
38
39
// Deserialize from bytes
40
ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
41
ObjectInputStream ois = new ObjectInputStream(bais);
42
Person deserialized = (Person) ois.readObject();
43
44
System.out.println(person.equals(deserialized)); // true
45
```
46
47
## Supported Types
48
49
The serialization extension automatically handles these non-serializable types:
50
51
```java { .api }
52
@SerializableAutoValue
53
@AutoValue
54
public abstract class TypesExample implements Serializable {
55
// Optional types
56
public abstract Optional<String> optionalString();
57
public abstract OptionalInt optionalInt();
58
public abstract OptionalLong optionalLong();
59
public abstract OptionalDouble optionalDouble();
60
61
// Guava Immutable Collections
62
public abstract ImmutableList<String> list();
63
public abstract ImmutableSet<Integer> set();
64
public abstract ImmutableMap<String, Object> map();
65
public abstract ImmutableMultimap<String, String> multimap();
66
public abstract ImmutableTable<String, String, Object> table();
67
68
// Other Guava types
69
public abstract ImmutableRangeSet<Integer> rangeSet();
70
public abstract ImmutableRangeMap<Integer, String> rangeMap();
71
72
public static TypesExample create(
73
Optional<String> optionalString,
74
OptionalInt optionalInt,
75
OptionalLong optionalLong,
76
OptionalDouble optionalDouble,
77
ImmutableList<String> list,
78
ImmutableSet<Integer> set,
79
ImmutableMap<String, Object> map,
80
ImmutableMultimap<String, String> multimap,
81
ImmutableTable<String, String, Object> table,
82
ImmutableRangeSet<Integer> rangeSet,
83
ImmutableRangeMap<Integer, String> rangeMap) {
84
return new AutoValue_TypesExample(
85
optionalString, optionalInt, optionalLong, optionalDouble,
86
list, set, map, multimap, table, rangeSet, rangeMap);
87
}
88
}
89
```
90
91
## Nested Serializable AutoValue
92
93
SerializableAutoValue works with nested AutoValue objects:
94
95
```java { .api }
96
@SerializableAutoValue
97
@AutoValue
98
public abstract class Address implements Serializable {
99
public abstract String street();
100
public abstract String city();
101
public abstract Optional<String> zipCode();
102
103
public static Address create(String street, String city, Optional<String> zipCode) {
104
return new AutoValue_Address(street, city, zipCode);
105
}
106
}
107
108
@SerializableAutoValue
109
@AutoValue
110
public abstract class Company implements Serializable {
111
public abstract String name();
112
public abstract Address headquarters();
113
public abstract ImmutableList<Address> offices();
114
public abstract ImmutableMap<String, Optional<String>> contacts();
115
116
public static Company create(
117
String name,
118
Address headquarters,
119
ImmutableList<Address> offices,
120
ImmutableMap<String, Optional<String>> contacts) {
121
return new AutoValue_Company(name, headquarters, offices, contacts);
122
}
123
}
124
```
125
126
## Custom Serializer Extensions
127
128
Create custom serializers for types not supported by default:
129
130
```java { .api }
131
// Custom type that needs serialization support
132
public class CustomType {
133
private final String data;
134
135
public CustomType(String data) {
136
this.data = data;
137
}
138
139
public String getData() {
140
return data;
141
}
142
}
143
144
// Custom serializer extension
145
public class CustomTypeSerializerExtension implements SerializerExtension {
146
@Override
147
public Optional<Serializer> getSerializer(
148
TypeMirror typeMirror,
149
SerializerFactory factory) {
150
if (isCustomType(typeMirror)) {
151
return Optional.of(new CustomTypeSerializer());
152
}
153
return Optional.empty();
154
}
155
156
private boolean isCustomType(TypeMirror type) {
157
return type.toString().equals(CustomType.class.getName());
158
}
159
160
private static class CustomTypeSerializer implements Serializer {
161
@Override
162
public TypeMirror proxyFieldType() {
163
return getTypeMirror(String.class);
164
}
165
166
@Override
167
public CodeBlock toProxy(CodeBlock expression) {
168
return CodeBlock.of("$L.getData()", expression);
169
}
170
171
@Override
172
public CodeBlock fromProxy(CodeBlock expression) {
173
return CodeBlock.of("new $T($L)", CustomType.class, expression);
174
}
175
}
176
}
177
```
178
179
Register the extension in `META-INF/services/com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension`.
180
181
## Serialization with Builders
182
183
SerializableAutoValue works seamlessly with builders:
184
185
```java { .api }
186
@SerializableAutoValue
187
@AutoValue
188
public abstract class Configuration implements Serializable {
189
public abstract String host();
190
public abstract Optional<Integer> port();
191
public abstract ImmutableSet<String> features();
192
public abstract ImmutableMap<String, String> properties();
193
194
public static Builder builder() {
195
return new AutoValue_Configuration.Builder()
196
.features(ImmutableSet.of())
197
.properties(ImmutableMap.of());
198
}
199
200
@AutoValue.Builder
201
public abstract static class Builder {
202
public abstract Builder host(String host);
203
public abstract Builder port(int port);
204
public abstract Builder features(Iterable<String> features);
205
public abstract Builder properties(Map<String, String> properties);
206
207
public abstract Builder addFeature(String feature);
208
public abstract Builder putProperty(String key, String value);
209
210
public abstract Configuration build();
211
}
212
}
213
```
214
215
Serialization works with builder-created objects:
216
217
```java
218
Configuration config = Configuration.builder()
219
.host("localhost")
220
.port(8080)
221
.addFeature("ssl")
222
.addFeature("compression")
223
.putProperty("timeout", "5000")
224
.build();
225
226
// Serialize and deserialize
227
byte[] serialized = serialize(config);
228
Configuration deserialized = deserialize(serialized);
229
System.out.println(config.equals(deserialized)); // true
230
```
231
232
## Generic SerializableAutoValue
233
234
Serialization supports generic types:
235
236
```java { .api }
237
@SerializableAutoValue
238
@AutoValue
239
public abstract class Container<T> implements Serializable {
240
public abstract T value();
241
public abstract Optional<String> label();
242
public abstract ImmutableList<T> alternatives();
243
244
public static <T> Container<T> create(
245
T value,
246
Optional<String> label,
247
ImmutableList<T> alternatives) {
248
return new AutoValue_Container<>(value, label, alternatives);
249
}
250
}
251
```
252
253
Usage with serialization:
254
255
```java
256
Container<String> stringContainer = Container.create(
257
"main value",
258
Optional.of("primary"),
259
ImmutableList.of("alt1", "alt2"));
260
261
// Serialization preserves generic type information
262
byte[] serialized = serialize(stringContainer);
263
Container<String> deserialized = deserialize(serialized);
264
```
265
266
## Error Handling
267
268
SerializableAutoValue provides clear errors for unsupported types:
269
270
```java
271
@SerializableAutoValue
272
@AutoValue
273
public abstract class UnsupportedExample implements Serializable {
274
// This will cause a compilation error
275
public abstract NonSerializableCustomType customField(); // ERROR: No serializer found
276
277
public static UnsupportedExample create(NonSerializableCustomType customField) {
278
return new AutoValue_UnsupportedExample(customField);
279
}
280
}
281
```
282
283
The error message will indicate which type needs a custom serializer.
284
285
## Serialization Performance
286
287
The generated serialization code is optimized:
288
289
- Uses direct field access (no reflection at runtime)
290
- Minimal object creation during serialization
291
- Efficient proxy objects for complex types
292
- Lazy initialization of serialization metadata
293
294
## Version Compatibility
295
296
Handle serialization version compatibility:
297
298
```java { .api }
299
@SerializableAutoValue
300
@AutoValue
301
public abstract class VersionedData implements Serializable {
302
private static final long serialVersionUID = 1L;
303
304
public abstract String name();
305
public abstract Optional<String> description();
306
public abstract ImmutableList<String> tags();
307
308
// Method to handle version compatibility
309
private Object readResolve() {
310
// Custom logic for handling old versions
311
return this;
312
}
313
314
public static VersionedData create(String name, Optional<String> description, ImmutableList<String> tags) {
315
return new AutoValue_VersionedData(name, description, tags);
316
}
317
}
318
```
319
320
## Integration with Other Extensions
321
322
SerializableAutoValue can be combined with other extensions:
323
324
```java { .api }
325
@SerializableAutoValue
326
@AutoValue
327
public abstract class CachedSerializableData implements Serializable {
328
public abstract String data();
329
public abstract Optional<ImmutableList<Integer>> values();
330
331
@Memoized
332
public String processedData() {
333
return data().toUpperCase().trim();
334
}
335
336
@Memoized
337
@Override
338
public abstract String toString();
339
340
public static CachedSerializableData create(String data, Optional<ImmutableList<Integer>> values) {
341
return new AutoValue_CachedSerializableData(data, values);
342
}
343
}
344
```
345
346
The memoized fields are properly handled during serialization/deserialization.
347
348
## Restrictions
349
350
- The AutoValue class must implement `Serializable`
351
- All custom types in properties must either be serializable or have custom serializers
352
- Generic type parameters must be serializable at runtime
353
- Builder classes are not automatically serializable (only the built objects are)