File: index.md

package info (click to toggle)
google-auto-common-java 1.1.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 3,112 kB
  • sloc: java: 36,145; xml: 1,512; sh: 34; makefile: 6
file content (281 lines) | stat: -rw-r--r-- 10,968 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# AutoValue


*Generated immutable value classes for Java 7+* <br />
***Éamonn McManus, Kevin Bourrillion*** <br />
**Google, Inc.**

> "AutoValue is a great tool for eliminating the drudgery of writing mundane
> value classes in Java. It encapsulates much of the advice in Effective Java
> Chapter 2, and frees you to concentrate on the more interesting aspects of
> your program. The resulting program is likely to be shorter, clearer, and
> freer of bugs. Two thumbs up."
>
> -- *Joshua Bloch, author, Effective Java*

## <a name="background"></a>Background

**Value classes** are extremely common in Java projects. These are classes for
which you want to treat any two instances with suitably equal field values as
interchangeable. That's right: we're talking about those classes where you wind
up implementing `equals`, `hashCode` and `toString` in a bloated, repetitive,
formulaic yet error-prone fashion.

Writing these methods the first time is not too bad, with the aid of a few
helper methods and IDE templates. But once written they continue to burden
reviewers, editors and future readers. Their wide expanses of boilerplate
sharply decrease the signal-to-noise ratio of your code... and they love to
harbor hard-to-spot bugs.

AutoValue provides an easier way to create immutable value classes, with a lot
less code and less room for error, while **not restricting your freedom** to
code almost any aspect of your class exactly the way you want it.

This page will walk you through how to use AutoValue. Looking for a little more
persuasion? Please see [Why AutoValue?](why.md).

## <a name="howto"></a>How to use AutoValue

The AutoValue concept is extremely simple: **You write an abstract class, and
AutoValue implements it.** That is all there is to it; there is literally *no*
configuration.

**Note:** Below, we will illustrate an AutoValue class *without* a generated
builder class. If you're more interested in the builder support, continue
reading at [AutoValue with Builders](builders.md) instead.

### <a name="example_java"></a>In your value class

Create your value class as an *abstract* class, with an abstract accessor method
for each desired property, and bearing the `@AutoValue` annotation.

```java
import com.google.auto.value.AutoValue;

@AutoValue
abstract class Animal {
  static Animal create(String name, int numberOfLegs) {
    return new AutoValue_Animal(name, numberOfLegs);
  }

  abstract String name();
  abstract int numberOfLegs();
}
```

The constructor parameters correspond, in order, to the abstract accessor
methods.

**For a nested class**, see ["How do I use AutoValue with a nested class"](howto.md#nested).

Note that in real life, some classes and methods would presumably be public and
have Javadoc. We're leaving these off in the User Guide only to keep the
examples short and simple.


### With Maven

You will need `auto-value-annotations-${auto-value.version}.jar` in your
compile-time classpath, and you will need `auto-value-${auto-value.version}.jar`
in your annotation-processor classpath.

For `auto-value-annotations`, you can write this in `pom.xml`:

```xml
<dependencies>
  <dependency>
    <groupId>com.google.auto.value</groupId>
    <artifactId>auto-value-annotations</artifactId>
    <version>${auto-value.version}</version>
  </dependency>
</dependencies>
```

Some AutoValue annotations have CLASS retention. This is mostly of use for
compile-time tools, such as AutoValue itself. If you are creating
a library, the end user rarely needs to know the original AutoValue annotations.
In that case, you can set the scope to `provided`, so that the user of your
library does not have `auto-value-annotations` as a transitive dependency.

```xml
<dependencies>
  <dependency>
    <groupId>com.google.auto.value</groupId>
    <artifactId>auto-value-annotations</artifactId>
    <version>${auto-value.version}</version>
    <scope>provided</scope>
  </dependency>
</dependencies>
```

For `auto-value` (the annotation processor), you can write this:

```xml
<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
        <annotationProcessorPaths>
          <path>
            <groupId>com.google.auto.value</groupId>
            <artifactId>auto-value</artifactId>
            <version>${auto-value.version}</version>
          </path>
        </annotationProcessorPaths>
      </configuration>
    </plugin>
  </plugins>
</build>
```

Alternatively, you can include the processor itself in your compile-time
classpath. Doing so may pull unnecessary classes into your runtime classpath.

```xml
<dependencies>
  <dependency>
    <groupId>com.google.auto.value</groupId>
    <artifactId>auto-value</artifactId>
    <version>${auto-value.version}</version>
    <optional>true</optional>
  </dependency>
</dependencies>
```

### With Gradle

Gradle users can declare the dependencies in their `build.gradle` script:

```groovy
dependencies {
  compileOnlyApi      "com.google.auto.value:auto-value-annotations:${autoValueVersion}"
  annotationProcessor "com.google.auto.value:auto-value:${autoValueVersion}"
}
```

Note: If you are using a version of Gradle prior to 6.7, use `compile` or (for
Android or java-library projects) `api` instead of `compileOnlyApi`. If you are
using a version prior to 4.6, you must apply an annotation processing plugin
[as described in these instructions][tbroyer-apt].

[tbroyer-apt]: https://plugins.gradle.org/plugin/net.ltgt.apt

### <a name="usage"></a>Usage

Your choice to use AutoValue is essentially *API-invisible*. This means that, to
the consumer of your class, your class looks and functions like any other. The
simple test below illustrates that behavior. Note that in real life, you would
write tests that actually *do something interesting* with the object, instead of
only checking field values going in and out.

```java
public void testAnimal() {
  Animal dog = Animal.create("dog", 4);
  assertEquals("dog", dog.name());
  assertEquals(4, dog.numberOfLegs());

  // You probably don't need to write assertions like these; just illustrating.
  assertTrue(Animal.create("dog", 4).equals(dog));
  assertFalse(Animal.create("cat", 4).equals(dog));
  assertFalse(Animal.create("dog", 2).equals(dog));

  assertEquals("Animal{name=dog, numberOfLegs=4}", dog.toString());
}
```

### <a name="whats_going_on"></a>What's going on here?

AutoValue runs inside `javac` as a standard annotation processor. It reads your
abstract class and infers what the implementation class should look like. It
generates source code, in your package, of a concrete implementation class
which extends your abstract class, having:

*   package visibility (non-public)
*   one field for each of your abstract accessor methods
*   a constructor that sets these fields
*   a concrete implementation of each accessor method returning the associated
    field value
*   an `equals` implementation that compares these values in the usual way
*   an appropriate corresponding `hashCode`
*   a `toString` implementation returning a useful (but unspecified) string
    representation of the instance

Your hand-written code, as shown above, delegates its factory method call to the
generated constructor and voilà!

For the `Animal` example shown above, here is [typical code AutoValue might
generate](generated-example.md).

Note that *consumers* of your value class *don't need to know any of this*. They
just invoke your provided factory method and get a well-behaved instance back.

## <a name="warnings"></a>Warnings

Be careful that you don't accidentally pass parameters to the generated
constructor in the wrong order. You must ensure that **your tests are
sufficient** to catch any field ordering problem. In most cases this should be
the natural outcome from testing whatever actual purpose this value class was
created for! In other cases a very simple test like the one shown above is
enough. Consider switching to use the [builder option](builders.md) to avoid
this problem.

We reserve the right to **change the `hashCode` implementation** at any time.
Never persist the result of `hashCode` or use it for any other unintended
purpose, and be careful never to depend on the order your values appear in
unordered collections like `HashSet`.

## <a name="why"></a>Why should I use AutoValue?

See [Why AutoValue?](why.md).

## <a name="versions"></a>What Java versions does it work with?

AutoValue requires that your compiler be at least Java 8. However, the code that
it generates is compatible with Java 7. That means that you can use it with
`-source 7 -target 7` or (for Java 9+) `--release 7`.

## <a name="more_howto"></a>How do I...

How do I...

*   ... [also generate a **builder** for my value class?](howto.md#builder)
*   ... [use AutoValue with a **nested** class?](howto.md#nested)
*   ... [use (or not use) JavaBeans-style name **prefixes**?](howto.md#beans)
*   ... [use **nullable** properties?](howto.md#nullable)
*   ... [perform other **validation**?](howto.md#validate)
*   ... [use a property of a **mutable** type?](howto.md#mutable_property)
*   ... [use a **custom** implementation of `equals`, etc.?](howto.md#custom)
*   ... [have AutoValue implement a concrete or default
    method?](howto.md#concrete)
*   ... [have multiple **`create`** methods, or name it/them
    differently?](howto.md#create)
*   ... [**ignore** certain properties in `equals`, etc.?](howto.md#ignore)
*   ... [have AutoValue also implement abstract methods from my
    **supertypes**?](howto.md#supertypes)
*   ... [use AutoValue with a **generic** class?](howto.md#generic)
*   ... [make my class Java- or GWT\-**serializable**?](howto.md#serialize)
*   ... [use AutoValue to **implement** an **annotation**
    type?](howto.md#annotation)
*   ... [also include **setter** (mutator) methods?](howto.md#setters)
*   ... [also generate **`compareTo`**?](howto.md#compareTo)
*   ... [use a **primitive array** for a property
    value?](howto.md#primitive_array)
*   ... [use an **object array** for a property value?](howto.md#object_array)
*   ... [have one `@AutoValue` class **extend** another?](howto.md#inherit)
*   ... [keep my accessor methods **private**?](howto.md#private_accessors)
*   ... [expose a **constructor**, not factory method, as my public creation
    API?](howto.md#public_constructor)
*   ... [use AutoValue on an **interface**, not abstract
    class?](howto.md#interface)
*   ... [**memoize** ("cache") derived properties?](howto.md#memoize)
*   ... [memoize the result of `hashCode` or
    `toString`?](howto.md#memoize_hash_tostring)
*   ... [make a class where only one of its properties is ever
    set?](howto.md#oneof)
*   ... [copy annotations from a class/method to the implemented
    class/method/field?](howto.md#copy_annotations)
*   ... [create a **pretty string** representation?](howto.md#toprettystring)


<!-- TODO(kevinb): should the above be only a selected subset? -->