0
# Value Classes
1
2
AutoValue generates immutable value classes that automatically implement equals(), hashCode(), and toString() methods with proper value semantics. Value classes are defined as abstract classes with abstract property getter methods.
3
4
## Basic Value Class
5
6
```java { .api }
7
@AutoValue
8
public abstract class BasicExample {
9
public abstract String name();
10
public abstract int age();
11
12
public static BasicExample create(String name, int age) {
13
return new AutoValue_BasicExample(name, age);
14
}
15
}
16
```
17
18
The generated class `AutoValue_BasicExample` will:
19
- Implement all abstract methods
20
- Provide proper equals() and hashCode() based on all properties
21
- Generate a readable toString() representation
22
- Be immutable (all fields are final)
23
24
## Usage Example
25
26
```java
27
BasicExample person = BasicExample.create("Alice", 30);
28
BasicExample samePerson = BasicExample.create("Alice", 30);
29
BasicExample differentPerson = BasicExample.create("Bob", 25);
30
31
System.out.println(person); // BasicExample{name=Alice, age=30}
32
System.out.println(person.equals(samePerson)); // true
33
System.out.println(person.equals(differentPerson)); // false
34
System.out.println(person.hashCode() == samePerson.hashCode()); // true
35
```
36
37
## Property Types
38
39
AutoValue supports all Java types as properties:
40
41
```java { .api }
42
@AutoValue
43
public abstract class TypesExample {
44
// Primitives
45
public abstract int intValue();
46
public abstract long longValue();
47
public abstract boolean booleanValue();
48
public abstract double doubleValue();
49
50
// Object types
51
public abstract String stringValue();
52
public abstract List<String> listValue();
53
public abstract Optional<Integer> optionalValue();
54
55
// Custom types
56
public abstract CustomClass customValue();
57
58
// Arrays
59
public abstract String[] arrayValue();
60
61
public static TypesExample create(
62
int intValue,
63
long longValue,
64
boolean booleanValue,
65
double doubleValue,
66
String stringValue,
67
List<String> listValue,
68
Optional<Integer> optionalValue,
69
CustomClass customValue,
70
String[] arrayValue) {
71
return new AutoValue_TypesExample(
72
intValue, longValue, booleanValue, doubleValue,
73
stringValue, listValue, optionalValue, customValue, arrayValue);
74
}
75
}
76
```
77
78
## Nullable Properties
79
80
Properties can be marked as nullable using any annotation named "Nullable":
81
82
```java { .api }
83
@AutoValue
84
public abstract class NullableExample {
85
@Nullable
86
public abstract String nullableProperty();
87
88
public abstract String requiredProperty();
89
90
public static NullableExample create(@Nullable String nullableProperty, String requiredProperty) {
91
return new AutoValue_NullableExample(nullableProperty, requiredProperty);
92
}
93
}
94
```
95
96
## Generic Value Classes
97
98
AutoValue supports generic type parameters:
99
100
```java { .api }
101
@AutoValue
102
public abstract class GenericExample<T, U> {
103
public abstract T firstValue();
104
public abstract U secondValue();
105
106
public static <T, U> GenericExample<T, U> create(T firstValue, U secondValue) {
107
return new AutoValue_GenericExample<>(firstValue, secondValue);
108
}
109
}
110
```
111
112
## Inheritance and Interfaces
113
114
AutoValue classes can implement interfaces and extend abstract classes:
115
116
```java { .api }
117
public interface Identifiable {
118
String getId();
119
}
120
121
@AutoValue
122
public abstract class IdentifiableEntity implements Identifiable {
123
@Override
124
public abstract String getId();
125
public abstract String name();
126
127
public static IdentifiableEntity create(String id, String name) {
128
return new AutoValue_IdentifiableEntity(id, name);
129
}
130
}
131
```
132
133
## Custom Methods
134
135
You can add custom methods to AutoValue classes:
136
137
```java { .api }
138
@AutoValue
139
public abstract class PersonWithMethods {
140
public abstract String firstName();
141
public abstract String lastName();
142
public abstract int age();
143
144
// Custom method
145
public String fullName() {
146
return firstName() + " " + lastName();
147
}
148
149
// Custom predicate
150
public boolean isAdult() {
151
return age() >= 18;
152
}
153
154
public static PersonWithMethods create(String firstName, String lastName, int age) {
155
return new AutoValue_PersonWithMethods(firstName, lastName, age);
156
}
157
}
158
```
159
160
## Annotation Copying
161
162
Control which annotations are copied to the generated implementation:
163
164
```java { .api }
165
@AutoValue
166
@CopyAnnotations // Copy class-level annotations
167
public abstract class AnnotatedExample {
168
@CopyAnnotations
169
@SuppressWarnings("example")
170
public abstract String annotatedProperty();
171
172
@CopyAnnotations(exclude = {Deprecated.class})
173
@Deprecated
174
@SuppressWarnings("example")
175
public abstract String selectivelyAnnotatedProperty();
176
177
public static AnnotatedExample create(String annotatedProperty, String selectivelyAnnotatedProperty) {
178
return new AutoValue_AnnotatedExample(annotatedProperty, selectivelyAnnotatedProperty);
179
}
180
}
181
```
182
183
## Validation
184
185
Add validation to factory methods:
186
187
```java { .api }
188
@AutoValue
189
public abstract class ValidatedExample {
190
public abstract String email();
191
public abstract int age();
192
193
public static ValidatedExample create(String email, int age) {
194
checkArgument(email.contains("@"), "Invalid email: %s", email);
195
checkArgument(age >= 0, "Age must be non-negative: %s", age);
196
return new AutoValue_ValidatedExample(email, age);
197
}
198
199
private static void checkArgument(boolean condition, String message, Object... args) {
200
if (!condition) {
201
throw new IllegalArgumentException(String.format(message, args));
202
}
203
}
204
}
205
```
206
207
## Collection Properties
208
209
AutoValue works well with immutable collections:
210
211
```java { .api }
212
@AutoValue
213
public abstract class CollectionExample {
214
public abstract ImmutableList<String> items();
215
public abstract ImmutableSet<Integer> values();
216
public abstract ImmutableMap<String, Object> properties();
217
218
public static CollectionExample create(
219
Iterable<String> items,
220
Iterable<Integer> values,
221
Map<String, Object> properties) {
222
return new AutoValue_CollectionExample(
223
ImmutableList.copyOf(items),
224
ImmutableSet.copyOf(values),
225
ImmutableMap.copyOf(properties));
226
}
227
}
228
```
229
230
## Error Handling
231
232
AutoValue generated constructors validate non-null parameters:
233
234
```java
235
// This will throw NullPointerException
236
PersonExample person = PersonExample.create(null, 25); // NPE: name cannot be null
237
238
// Use Optional for nullable values instead
239
@AutoValue
240
public abstract class SafeExample {
241
public abstract Optional<String> optionalName();
242
public abstract int age();
243
244
public static SafeExample create(@Nullable String name, int age) {
245
return new AutoValue_SafeExample(Optional.ofNullable(name), age);
246
}
247
}
248
```
249
250
## Performance Considerations
251
252
- Generated equals() methods use efficient short-circuiting
253
- hashCode() is computed once and cached
254
- toString() builds strings efficiently
255
- All fields are final, enabling JVM optimizations
256
- No reflection is used at runtime