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