• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# AutoValue
2
3
4*Generated immutable value classes for Java 7+* <br />
5***Éamonn McManus, Kevin Bourrillion*** <br />
6**Google, Inc.**
7
8> "AutoValue is a great tool for eliminating the drudgery of writing mundane
9> value classes in Java. It encapsulates much of the advice in Effective Java
10> Chapter 2, and frees you to concentrate on the more interesting aspects of
11> your program. The resulting program is likely to be shorter, clearer, and
12> freer of bugs. Two thumbs up."
13>
14> -- *Joshua Bloch, author, Effective Java*
15
16## <a name="background"></a>Background
17
18**Value classes** are extremely common in Java projects. These are classes for
19which you want to treat any two instances with suitably equal field values as
20interchangeable. That's right: we're talking about those classes where you wind
21up implementing `equals`, `hashCode` and `toString` in a bloated, repetitive,
22formulaic yet error-prone fashion.
23
24Writing these methods the first time is not too bad, with the aid of a few
25helper methods and IDE templates. But once written they continue to burden
26reviewers, editors and future readers. Their wide expanses of boilerplate
27sharply decrease the signal-to-noise ratio of your code... and they love to
28harbor hard-to-spot bugs.
29
30AutoValue provides an easier way to create immutable value classes, with a lot
31less code and less room for error, while **not restricting your freedom** to
32code almost any aspect of your class exactly the way you want it.
33
34This page will walk you through how to use AutoValue. Looking for a little more
35persuasion? Please see [Why AutoValue?](why.md).
36
37## <a name="howto"></a>How to use AutoValue
38
39The AutoValue concept is extremely simple: **You write an abstract class, and
40AutoValue implements it.** That is all there is to it; there is literally *no*
41configuration.
42
43**Note:** Below, we will illustrate an AutoValue class *without* a generated
44builder class. If you're more interested in the builder support, continue
45reading at [AutoValue with Builders](builders.md) instead.
46
47### <a name="example_java"></a>In your value class
48
49Create your value class as an *abstract* class, with an abstract accessor method
50for each desired property, and bearing the `@AutoValue` annotation.
51
52```java
53import com.google.auto.value.AutoValue;
54
55@AutoValue
56abstract class Animal {
57  static Animal create(String name, int numberOfLegs) {
58    return new AutoValue_Animal(name, numberOfLegs);
59  }
60
61  abstract String name();
62  abstract int numberOfLegs();
63}
64```
65
66The constructor parameters correspond, in order, to the abstract accessor
67methods.
68
69**For a nested class**, see ["How do I use AutoValue with a nested class"](howto.md#nested).
70
71Note that in real life, some classes and methods would presumably be public and
72have Javadoc. We're leaving these off in the User Guide only to keep the
73examples short and simple.
74
75
76### With Maven
77
78You will need `auto-value-annotations-${auto-value.version}.jar` in your
79compile-time classpath, and you will need `auto-value-${auto-value.version}.jar`
80in your annotation-processor classpath.
81
82For `auto-value-annotations`, you can write this in `pom.xml`:
83
84```xml
85<dependencies>
86  <dependency>
87    <groupId>com.google.auto.value</groupId>
88    <artifactId>auto-value-annotations</artifactId>
89    <version>${auto-value.version}</version>
90  </dependency>
91</dependencies>
92```
93
94Some AutoValue annotations have CLASS retention. This is mostly of use for
95compile-time tools, such as AutoValue itself. If you are creating
96a library, the end user rarely needs to know the original AutoValue annotations.
97In that case, you can set the scope to `provided`, so that the user of your
98library does not have `auto-value-annotations` as a transitive dependency.
99
100```xml
101<dependencies>
102  <dependency>
103    <groupId>com.google.auto.value</groupId>
104    <artifactId>auto-value-annotations</artifactId>
105    <version>${auto-value.version}</version>
106    <scope>provided</scope>
107  </dependency>
108</dependencies>
109```
110
111For `auto-value` (the annotation processor), you can write this:
112
113```xml
114<build>
115  <plugins>
116    <plugin>
117      <artifactId>maven-compiler-plugin</artifactId>
118      <configuration>
119        <annotationProcessorPaths>
120          <path>
121            <groupId>com.google.auto.value</groupId>
122            <artifactId>auto-value</artifactId>
123            <version>${auto-value.version}</version>
124          </path>
125        </annotationProcessorPaths>
126      </configuration>
127    </plugin>
128  </plugins>
129</build>
130```
131
132Alternatively, you can include the processor itself in your compile-time
133classpath. Doing so may pull unnecessary classes into your runtime classpath.
134
135```xml
136<dependencies>
137  <dependency>
138    <groupId>com.google.auto.value</groupId>
139    <artifactId>auto-value</artifactId>
140    <version>${auto-value.version}</version>
141    <optional>true</optional>
142  </dependency>
143</dependencies>
144```
145
146### With Gradle
147
148Gradle users can declare the dependencies in their `build.gradle` script:
149
150```groovy
151dependencies {
152  compileOnlyApi      "com.google.auto.value:auto-value-annotations:${autoValueVersion}"
153  annotationProcessor "com.google.auto.value:auto-value:${autoValueVersion}"
154}
155```
156
157Note: If you are using a version of Gradle prior to 6.7, use `compile` or (for
158Android or java-library projects) `api` instead of `compileOnlyApi`. If you are
159using a version prior to 4.6, you must apply an annotation processing plugin
160[as described in these instructions][tbroyer-apt].
161
162[tbroyer-apt]: https://plugins.gradle.org/plugin/net.ltgt.apt
163
164### <a name="usage"></a>Usage
165
166Your choice to use AutoValue is essentially *API-invisible*. This means that, to
167the consumer of your class, your class looks and functions like any other. The
168simple test below illustrates that behavior. Note that in real life, you would
169write tests that actually *do something interesting* with the object, instead of
170only checking field values going in and out.
171
172```java
173public void testAnimal() {
174  Animal dog = Animal.create("dog", 4);
175  assertEquals("dog", dog.name());
176  assertEquals(4, dog.numberOfLegs());
177
178  // You probably don't need to write assertions like these; just illustrating.
179  assertTrue(Animal.create("dog", 4).equals(dog));
180  assertFalse(Animal.create("cat", 4).equals(dog));
181  assertFalse(Animal.create("dog", 2).equals(dog));
182
183  assertEquals("Animal{name=dog, numberOfLegs=4}", dog.toString());
184}
185```
186
187### <a name="whats_going_on"></a>What's going on here?
188
189AutoValue runs inside `javac` as a standard annotation processor. It reads your
190abstract class and infers what the implementation class should look like. It
191generates source code, in your package, of a concrete implementation class
192which extends your abstract class, having:
193
194*   package visibility (non-public)
195*   one field for each of your abstract accessor methods
196*   a constructor that sets these fields
197*   a concrete implementation of each accessor method returning the associated
198    field value
199*   an `equals` implementation that compares these values in the usual way
200*   an appropriate corresponding `hashCode`
201*   a `toString` implementation returning a useful (but unspecified) string
202    representation of the instance
203
204Your hand-written code, as shown above, delegates its factory method call to the
205generated constructor and voilà!
206
207For the `Animal` example shown above, here is [typical code AutoValue might
208generate](generated-example.md).
209
210Note that *consumers* of your value class *don't need to know any of this*. They
211just invoke your provided factory method and get a well-behaved instance back.
212
213## <a name="warnings"></a>Warnings
214
215Be careful that you don't accidentally pass parameters to the generated
216constructor in the wrong order. You must ensure that **your tests are
217sufficient** to catch any field ordering problem. In most cases this should be
218the natural outcome from testing whatever actual purpose this value class was
219created for! In other cases a very simple test like the one shown above is
220enough. Consider switching to use the [builder option](builders.md) to avoid
221this problem.
222
223We reserve the right to **change the `hashCode` implementation** at any time.
224Never persist the result of `hashCode` or use it for any other unintended
225purpose, and be careful never to depend on the order your values appear in
226unordered collections like `HashSet`.
227
228## <a name="why"></a>Why should I use AutoValue?
229
230See [Why AutoValue?](why.md).
231
232## <a name="versions"></a>What Java versions does it work with?
233
234AutoValue requires that your compiler be at least Java 8. However, the code that
235it generates is compatible with Java 7. That means that you can use it with
236`-source 7 -target 7` or (for Java 9+) `--release 7`.
237
238## <a name="more_howto"></a>How do I...
239
240How do I...
241
242*   ... [also generate a **builder** for my value class?](howto.md#builder)
243*   ... [use AutoValue with a **nested** class?](howto.md#nested)
244*   ... [use (or not use) JavaBeans-style name **prefixes**?](howto.md#beans)
245*   ... [use **nullable** properties?](howto.md#nullable)
246*   ... [perform other **validation**?](howto.md#validate)
247*   ... [use a property of a **mutable** type?](howto.md#mutable_property)
248*   ... [use a **custom** implementation of `equals`, etc.?](howto.md#custom)
249*   ... [have AutoValue implement a concrete or default
250    method?](howto.md#concrete)
251*   ... [have multiple **`create`** methods, or name it/them
252    differently?](howto.md#create)
253*   ... [**ignore** certain properties in `equals`, etc.?](howto.md#ignore)
254*   ... [have AutoValue also implement abstract methods from my
255    **supertypes**?](howto.md#supertypes)
256*   ... [use AutoValue with a **generic** class?](howto.md#generic)
257*   ... [make my class Java- or GWT\-**serializable**?](howto.md#serialize)
258*   ... [use AutoValue to **implement** an **annotation**
259    type?](howto.md#annotation)
260*   ... [also include **setter** (mutator) methods?](howto.md#setters)
261*   ... [also generate **`compareTo`**?](howto.md#compareTo)
262*   ... [use a **primitive array** for a property
263    value?](howto.md#primitive_array)
264*   ... [use an **object array** for a property value?](howto.md#object_array)
265*   ... [have one `@AutoValue` class **extend** another?](howto.md#inherit)
266*   ... [keep my accessor methods **private**?](howto.md#private_accessors)
267*   ... [expose a **constructor**, not factory method, as my public creation
268    API?](howto.md#public_constructor)
269*   ... [use AutoValue on an **interface**, not abstract
270    class?](howto.md#interface)
271*   ... [**memoize** ("cache") derived properties?](howto.md#memoize)
272*   ... [memoize the result of `hashCode` or
273    `toString`?](howto.md#memoize_hash_tostring)
274*   ... [make a class where only one of its properties is ever
275    set?](howto.md#oneof)
276*   ... [copy annotations from a class/method to the implemented
277    class/method/field?](howto.md#copy_annotations)
278*   ... [create a **pretty string** representation?](howto.md#toprettystring)
279
280
281<!-- TODO(kevinb): should the above be only a selected subset? -->
282