xref: /aosp_15_r20/external/auto/value/userguide/howto.md (revision 1c2bbba85eccddce6de79cbbf1645fda32e723f0)
1*1c2bbba8SAndroid Build Coastguard Worker# How do I...
2*1c2bbba8SAndroid Build Coastguard Worker
3*1c2bbba8SAndroid Build Coastguard Worker
4*1c2bbba8SAndroid Build Coastguard WorkerThis page answers common how-to questions that may come up when using AutoValue.
5*1c2bbba8SAndroid Build Coastguard WorkerYou should read and understand the [Introduction](index.md) first.
6*1c2bbba8SAndroid Build Coastguard Worker
7*1c2bbba8SAndroid Build Coastguard WorkerQuestions specific to usage of the **builder option** are documented separately;
8*1c2bbba8SAndroid Build Coastguard Workerfor this, start by reading [AutoValue with builders](builders.md).
9*1c2bbba8SAndroid Build Coastguard Worker
10*1c2bbba8SAndroid Build Coastguard Worker## Contents
11*1c2bbba8SAndroid Build Coastguard Worker
12*1c2bbba8SAndroid Build Coastguard WorkerHow do I...
13*1c2bbba8SAndroid Build Coastguard Worker
14*1c2bbba8SAndroid Build Coastguard Worker*   ... [also generate a **builder** for my value class?](#builder)
15*1c2bbba8SAndroid Build Coastguard Worker*   ... [use AutoValue with a **nested** class?](#nested)
16*1c2bbba8SAndroid Build Coastguard Worker*   ... [use (or not use) JavaBeans-style name **prefixes**?](#beans)
17*1c2bbba8SAndroid Build Coastguard Worker*   ... [use **nullable** properties?](#nullable)
18*1c2bbba8SAndroid Build Coastguard Worker*   ... [perform other **validation**?](#validate)
19*1c2bbba8SAndroid Build Coastguard Worker*   ... [use a property of a **mutable** type?](#mutable_property)
20*1c2bbba8SAndroid Build Coastguard Worker*   ... [use a **custom** implementation of `equals`, etc.?](#custom)
21*1c2bbba8SAndroid Build Coastguard Worker*   ... [have AutoValue implement a concrete or default method?](#concrete)
22*1c2bbba8SAndroid Build Coastguard Worker*   ... [have multiple **`create`** methods, or name it/them
23*1c2bbba8SAndroid Build Coastguard Worker    differently?](#create)
24*1c2bbba8SAndroid Build Coastguard Worker*   ... [**ignore** certain properties in `equals`, etc.?](#ignore)
25*1c2bbba8SAndroid Build Coastguard Worker*   ... [have AutoValue also implement abstract methods from my
26*1c2bbba8SAndroid Build Coastguard Worker    **supertypes**?](#supertypes)
27*1c2bbba8SAndroid Build Coastguard Worker*   ... [use AutoValue with a **generic** class?](#generic)
28*1c2bbba8SAndroid Build Coastguard Worker*   ... [make my class Java- or GWT\-**serializable**?](#serialize)
29*1c2bbba8SAndroid Build Coastguard Worker*   ... [use AutoValue to **implement** an **annotation** type?](#annotation)
30*1c2bbba8SAndroid Build Coastguard Worker*   ... [also include **setter** (mutator) methods?](#setters)
31*1c2bbba8SAndroid Build Coastguard Worker*   ... [also generate **`compareTo`**?](#compareTo)
32*1c2bbba8SAndroid Build Coastguard Worker*   ... [use a **primitive array** for a property value?](#primitive_array)
33*1c2bbba8SAndroid Build Coastguard Worker*   ... [use an **object array** for a property value?](#object_array)
34*1c2bbba8SAndroid Build Coastguard Worker*   ... [have one `@AutoValue` class **extend** another?](#inherit)
35*1c2bbba8SAndroid Build Coastguard Worker*   ... [keep my accessor methods **private**?](#private_accessors)
36*1c2bbba8SAndroid Build Coastguard Worker*   ... [expose a **constructor**, not factory method, as my public creation
37*1c2bbba8SAndroid Build Coastguard Worker    API?](#public_constructor)
38*1c2bbba8SAndroid Build Coastguard Worker*   ... [use AutoValue on an **interface**, not abstract class?](#interface)
39*1c2bbba8SAndroid Build Coastguard Worker*   ... [**memoize** ("cache") derived properties?](#memoize)
40*1c2bbba8SAndroid Build Coastguard Worker*   ... [memoize the result of `hashCode` or
41*1c2bbba8SAndroid Build Coastguard Worker    `toString`?](#memoize_hash_tostring)
42*1c2bbba8SAndroid Build Coastguard Worker*   ... [make a class where only one of its properties is ever set?](#oneof)
43*1c2bbba8SAndroid Build Coastguard Worker*   ... [copy annotations from a class/method to the implemented
44*1c2bbba8SAndroid Build Coastguard Worker    class/method/field?](#copy_annotations)
45*1c2bbba8SAndroid Build Coastguard Worker*   ... [create a **pretty string** representation?](#toprettystring)
46*1c2bbba8SAndroid Build Coastguard Worker
47*1c2bbba8SAndroid Build Coastguard Worker## <a name="builder"></a>... also generate a builder for my value class?
48*1c2bbba8SAndroid Build Coastguard Worker
49*1c2bbba8SAndroid Build Coastguard WorkerPlease see [AutoValue with builders](builders.md).
50*1c2bbba8SAndroid Build Coastguard Worker
51*1c2bbba8SAndroid Build Coastguard Worker## <a name="nested"></a>... use AutoValue with a nested class?
52*1c2bbba8SAndroid Build Coastguard Worker
53*1c2bbba8SAndroid Build Coastguard WorkerAutoValue composes the generated class name in the form
54*1c2bbba8SAndroid Build Coastguard Worker`AutoValue_`*`Outer_Middle_Inner`*.
55*1c2bbba8SAndroid Build Coastguard WorkerAs many of these segments will be used in the generated name as required.
56*1c2bbba8SAndroid Build Coastguard WorkerOnly the simple class name will appear in `toString` output.
57*1c2bbba8SAndroid Build Coastguard Worker
58*1c2bbba8SAndroid Build Coastguard Worker```java
59*1c2bbba8SAndroid Build Coastguard Workerclass Outer {
60*1c2bbba8SAndroid Build Coastguard Worker  static class Middle {
61*1c2bbba8SAndroid Build Coastguard Worker    @AutoValue
62*1c2bbba8SAndroid Build Coastguard Worker    abstract static class Inner {
63*1c2bbba8SAndroid Build Coastguard Worker      static Inner create(String foo) {
64*1c2bbba8SAndroid Build Coastguard Worker        return new AutoValue_Outer_Middle_Inner(foo);
65*1c2bbba8SAndroid Build Coastguard Worker      }
66*1c2bbba8SAndroid Build Coastguard Worker      ...
67*1c2bbba8SAndroid Build Coastguard Worker```
68*1c2bbba8SAndroid Build Coastguard Worker
69*1c2bbba8SAndroid Build Coastguard Worker## <a name="beans"></a>... use (or not use) JavaBeans-style name prefixes?
70*1c2bbba8SAndroid Build Coastguard Worker
71*1c2bbba8SAndroid Build Coastguard WorkerSome developers prefer to name their accessors with a `get-` or `is-` prefix,
72*1c2bbba8SAndroid Build Coastguard Workerbut would prefer that only the "bare" property name be used in `toString` and
73*1c2bbba8SAndroid Build Coastguard Workerfor the generated constructor's parameter names.
74*1c2bbba8SAndroid Build Coastguard Worker
75*1c2bbba8SAndroid Build Coastguard WorkerAutoValue will do exactly this, but only if you are using these prefixes
76*1c2bbba8SAndroid Build Coastguard Worker*consistently*. In that case, it infers your intended property name by first
77*1c2bbba8SAndroid Build Coastguard Workerstripping the `get-` or `is-` prefix, then adjusting the case of what remains as
78*1c2bbba8SAndroid Build Coastguard Workerspecified by
79*1c2bbba8SAndroid Build Coastguard Worker[Introspector.decapitalize](http://docs.oracle.com/javase/8/docs/api/java/beans/Introspector.html#decapitalize).
80*1c2bbba8SAndroid Build Coastguard Worker
81*1c2bbba8SAndroid Build Coastguard WorkerNote that, in keeping with the JavaBeans specification, the `is-` prefix is only
82*1c2bbba8SAndroid Build Coastguard Workerallowed on `boolean`-returning methods. `get-` is allowed on any type of
83*1c2bbba8SAndroid Build Coastguard Workeraccessor.
84*1c2bbba8SAndroid Build Coastguard Worker
85*1c2bbba8SAndroid Build Coastguard Worker## <a name="nullable"></a>... use nullable properties?
86*1c2bbba8SAndroid Build Coastguard Worker
87*1c2bbba8SAndroid Build Coastguard WorkerOrdinarily the generated constructor will reject any null values. If you want to
88*1c2bbba8SAndroid Build Coastguard Workeraccept null, simply apply any annotation named `@Nullable` to the appropriate
89*1c2bbba8SAndroid Build Coastguard Workeraccessor methods. This causes AutoValue to remove the null checks and generate
90*1c2bbba8SAndroid Build Coastguard Workernull-friendly code for `equals`, `hashCode` and `toString`. Example:
91*1c2bbba8SAndroid Build Coastguard Worker
92*1c2bbba8SAndroid Build Coastguard Worker```java
93*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
94*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Foo {
95*1c2bbba8SAndroid Build Coastguard Worker  public static Foo create(@Nullable Bar bar) {
96*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Foo(bar);
97*1c2bbba8SAndroid Build Coastguard Worker  }
98*1c2bbba8SAndroid Build Coastguard Worker
99*1c2bbba8SAndroid Build Coastguard Worker  @Nullable abstract Bar bar();
100*1c2bbba8SAndroid Build Coastguard Worker}
101*1c2bbba8SAndroid Build Coastguard Worker```
102*1c2bbba8SAndroid Build Coastguard Worker
103*1c2bbba8SAndroid Build Coastguard WorkerThis example also shows annotating the corresponding `create` parameter with
104*1c2bbba8SAndroid Build Coastguard Worker`@Nullable`. AutoValue does not actually require this annotation, only the one
105*1c2bbba8SAndroid Build Coastguard Workeron the accessor, but we recommended it as useful documentation to your caller.
106*1c2bbba8SAndroid Build Coastguard WorkerConversely, if `@Nullable` is only added to the parameter in `create` (or
107*1c2bbba8SAndroid Build Coastguard Workersimilarly the setter method of [AutoValue.Builder](builders)), but not the
108*1c2bbba8SAndroid Build Coastguard Workercorresponding accessor method, it won't have any effect.
109*1c2bbba8SAndroid Build Coastguard Worker
110*1c2bbba8SAndroid Build Coastguard Worker## <a name="validate"></a>... perform other validation?
111*1c2bbba8SAndroid Build Coastguard Worker
112*1c2bbba8SAndroid Build Coastguard WorkerNull checks are added automatically (as [above](#nullable)). For other types of
113*1c2bbba8SAndroid Build Coastguard Workerprecondition checks or pre-processing, just add them to your factory method:
114*1c2bbba8SAndroid Build Coastguard Worker
115*1c2bbba8SAndroid Build Coastguard Worker```java
116*1c2bbba8SAndroid Build Coastguard Workerstatic MyType create(String first, String second) {
117*1c2bbba8SAndroid Build Coastguard Worker  checkArgument(!first.isEmpty());
118*1c2bbba8SAndroid Build Coastguard Worker  return new AutoValue_MyType(first, second.trim());
119*1c2bbba8SAndroid Build Coastguard Worker}
120*1c2bbba8SAndroid Build Coastguard Worker```
121*1c2bbba8SAndroid Build Coastguard Worker
122*1c2bbba8SAndroid Build Coastguard Worker## <a name="mutable_property"></a>... use a property of a mutable type?
123*1c2bbba8SAndroid Build Coastguard Worker
124*1c2bbba8SAndroid Build Coastguard WorkerAutoValue classes are meant and expected to be immutable. But sometimes you
125*1c2bbba8SAndroid Build Coastguard Workerwould want to take a mutable type and use it as a property. In these cases:
126*1c2bbba8SAndroid Build Coastguard Worker
127*1c2bbba8SAndroid Build Coastguard WorkerFirst, check if the mutable type has a corresponding immutable cousin. For
128*1c2bbba8SAndroid Build Coastguard Workerexample, the types `List<String>` and `String[]` have the immutable counterpart
129*1c2bbba8SAndroid Build Coastguard Worker`ImmutableList<String>` in [Guava](http://github.com/google/guava). If so, use
130*1c2bbba8SAndroid Build Coastguard Workerthe immutable type for your property, and only accept the mutable type during
131*1c2bbba8SAndroid Build Coastguard Workerconstruction:
132*1c2bbba8SAndroid Build Coastguard Worker
133*1c2bbba8SAndroid Build Coastguard Worker```java
134*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
135*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class ListExample {
136*1c2bbba8SAndroid Build Coastguard Worker  public static ListExample create(String[] mutableNames) {
137*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_ListExample(ImmutableList.copyOf(mutableNames));
138*1c2bbba8SAndroid Build Coastguard Worker  }
139*1c2bbba8SAndroid Build Coastguard Worker
140*1c2bbba8SAndroid Build Coastguard Worker  public abstract ImmutableList<String> names();
141*1c2bbba8SAndroid Build Coastguard Worker}
142*1c2bbba8SAndroid Build Coastguard Worker```
143*1c2bbba8SAndroid Build Coastguard Worker
144*1c2bbba8SAndroid Build Coastguard WorkerNote: this is a perfectly sensible practice, not an ugly workaround!
145*1c2bbba8SAndroid Build Coastguard Worker
146*1c2bbba8SAndroid Build Coastguard WorkerIf there is no suitable immutable type to use, you'll need to proceed with
147*1c2bbba8SAndroid Build Coastguard Workercaution. Your static factory method should pass a *clone* of the passed object
148*1c2bbba8SAndroid Build Coastguard Workerto the generated constructor. Your accessor method should document a very loud
149*1c2bbba8SAndroid Build Coastguard Workerwarning never to mutate the object returned.
150*1c2bbba8SAndroid Build Coastguard Worker
151*1c2bbba8SAndroid Build Coastguard Worker```java
152*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
153*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class MutableExample {
154*1c2bbba8SAndroid Build Coastguard Worker  public static MutableExample create(MutablePropertyType ouch) {
155*1c2bbba8SAndroid Build Coastguard Worker    // Replace `MutablePropertyType.copyOf()` below with the right copying code for this type
156*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_MutableExample(MutablePropertyType.copyOf(ouch));
157*1c2bbba8SAndroid Build Coastguard Worker  }
158*1c2bbba8SAndroid Build Coastguard Worker
159*1c2bbba8SAndroid Build Coastguard Worker  /**
160*1c2bbba8SAndroid Build Coastguard Worker   * Returns the ouch associated with this object; <b>do not mutate</b> the
161*1c2bbba8SAndroid Build Coastguard Worker   * returned object.
162*1c2bbba8SAndroid Build Coastguard Worker   */
163*1c2bbba8SAndroid Build Coastguard Worker  public abstract MutablePropertyType ouch();
164*1c2bbba8SAndroid Build Coastguard Worker}
165*1c2bbba8SAndroid Build Coastguard Worker```
166*1c2bbba8SAndroid Build Coastguard Worker
167*1c2bbba8SAndroid Build Coastguard WorkerWarning: this is an ugly workaround, not a perfectly sensible practice! Callers
168*1c2bbba8SAndroid Build Coastguard Workercan trivially break the invariants of the immutable class by mutating the
169*1c2bbba8SAndroid Build Coastguard Workeraccessor's return value. An example where something can go wrong: AutoValue
170*1c2bbba8SAndroid Build Coastguard Workerobjects can be used as keys in Maps.
171*1c2bbba8SAndroid Build Coastguard Worker
172*1c2bbba8SAndroid Build Coastguard Worker## <a name="custom"></a>... use a custom implementation of `equals`, etc.?
173*1c2bbba8SAndroid Build Coastguard Worker
174*1c2bbba8SAndroid Build Coastguard WorkerSimply write your custom implementation; AutoValue will notice this and will
175*1c2bbba8SAndroid Build Coastguard Workerskip generating its own. Your hand-written logic will thus be inherited on the
176*1c2bbba8SAndroid Build Coastguard Workerconcrete implementation class. We call this *underriding* the method.
177*1c2bbba8SAndroid Build Coastguard Worker
178*1c2bbba8SAndroid Build Coastguard WorkerRemember when doing this that you are losing AutoValue's protections. Be careful
179*1c2bbba8SAndroid Build Coastguard Workerto follow the basic rules of hash codes: equal objects must have equal hash
180*1c2bbba8SAndroid Build Coastguard Workercodes *always*, and equal hash codes should imply equal objects *almost always*.
181*1c2bbba8SAndroid Build Coastguard WorkerYou should now test your class more thoroughly, ideally using
182*1c2bbba8SAndroid Build Coastguard Worker[`EqualsTester`](http://static.javadoc.io/com.google.guava/guava-testlib/19.0/com/google/common/testing/EqualsTester.html)
183*1c2bbba8SAndroid Build Coastguard Workerfrom [guava-testlib](http://github.com/google/guava).
184*1c2bbba8SAndroid Build Coastguard Worker
185*1c2bbba8SAndroid Build Coastguard WorkerBest practice: mark your underriding methods `final` to make it clear to future
186*1c2bbba8SAndroid Build Coastguard Workerreaders that these methods aren't overridden by AutoValue.
187*1c2bbba8SAndroid Build Coastguard Worker
188*1c2bbba8SAndroid Build Coastguard Worker## <a name="concrete"></a>... have AutoValue implement a concrete or default method?
189*1c2bbba8SAndroid Build Coastguard Worker
190*1c2bbba8SAndroid Build Coastguard WorkerIf a parent class defines a concrete (non-abstract) method that you would like
191*1c2bbba8SAndroid Build Coastguard WorkerAutoValue to implement, you can *redeclare* it as abstract. This applies to
192*1c2bbba8SAndroid Build Coastguard Worker`Object` methods like `toString()`, but also to property methods that you would
193*1c2bbba8SAndroid Build Coastguard Workerlike to have AutoValue implement. It also applies to default methods in
194*1c2bbba8SAndroid Build Coastguard Workerinterfaces.
195*1c2bbba8SAndroid Build Coastguard Worker
196*1c2bbba8SAndroid Build Coastguard Worker```java
197*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
198*1c2bbba8SAndroid Build Coastguard Workerclass PleaseOverrideExample extends SuperclassThatDefinesToString {
199*1c2bbba8SAndroid Build Coastguard Worker  ...
200*1c2bbba8SAndroid Build Coastguard Worker
201*1c2bbba8SAndroid Build Coastguard Worker  // cause AutoValue to generate this even though the superclass has it
202*1c2bbba8SAndroid Build Coastguard Worker  @Override public abstract String toString();
203*1c2bbba8SAndroid Build Coastguard Worker}
204*1c2bbba8SAndroid Build Coastguard Worker```
205*1c2bbba8SAndroid Build Coastguard Worker
206*1c2bbba8SAndroid Build Coastguard Worker```java
207*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
208*1c2bbba8SAndroid Build Coastguard Workerclass PleaseReimplementDefaultMethod implements InterfaceWithDefaultMethod {
209*1c2bbba8SAndroid Build Coastguard Worker  ...
210*1c2bbba8SAndroid Build Coastguard Worker
211*1c2bbba8SAndroid Build Coastguard Worker  // cause AutoValue to implement this even though the interface has a default
212*1c2bbba8SAndroid Build Coastguard Worker  // implementation
213*1c2bbba8SAndroid Build Coastguard Worker  @Override public abstract int numberOfLegs();
214*1c2bbba8SAndroid Build Coastguard Worker}
215*1c2bbba8SAndroid Build Coastguard Worker```
216*1c2bbba8SAndroid Build Coastguard Worker
217*1c2bbba8SAndroid Build Coastguard Worker## <a name="create"></a>... have multiple `create` methods, or name it/them differently?
218*1c2bbba8SAndroid Build Coastguard Worker
219*1c2bbba8SAndroid Build Coastguard WorkerJust do it! AutoValue doesn't actually care. This
220*1c2bbba8SAndroid Build Coastguard Worker[best practice item](practices.md#one_reference) may be relevant.
221*1c2bbba8SAndroid Build Coastguard Worker
222*1c2bbba8SAndroid Build Coastguard Worker## <a name="ignore"></a>... ignore certain properties in `equals`, etc.?
223*1c2bbba8SAndroid Build Coastguard Worker
224*1c2bbba8SAndroid Build Coastguard WorkerSuppose your value class has an extra field that shouldn't be included in
225*1c2bbba8SAndroid Build Coastguard Worker`equals` or `hashCode` computations.
226*1c2bbba8SAndroid Build Coastguard Worker
227*1c2bbba8SAndroid Build Coastguard WorkerIf this is because it is a derived value based on other properties, see [How do
228*1c2bbba8SAndroid Build Coastguard WorkerI memoize derived properties?](#memoize).
229*1c2bbba8SAndroid Build Coastguard Worker
230*1c2bbba8SAndroid Build Coastguard WorkerOtherwise, first make certain that you really want to do this. It is often, but
231*1c2bbba8SAndroid Build Coastguard Workernot always, a mistake. Remember that libraries will treat two equal instances as
232*1c2bbba8SAndroid Build Coastguard Workerabsolutely *interchangeable* with each other. Whatever information is present in
233*1c2bbba8SAndroid Build Coastguard Workerthis extra field could essentially "disappear" when you aren't expecting it, for
234*1c2bbba8SAndroid Build Coastguard Workerexample when your value is stored and retrieved from certain collections.
235*1c2bbba8SAndroid Build Coastguard Worker
236*1c2bbba8SAndroid Build Coastguard WorkerIf you're sure, here is how to do it:
237*1c2bbba8SAndroid Build Coastguard Worker
238*1c2bbba8SAndroid Build Coastguard Worker```java
239*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
240*1c2bbba8SAndroid Build Coastguard Workerabstract class IgnoreExample {
241*1c2bbba8SAndroid Build Coastguard Worker  static IgnoreExample create(String normalProperty, String ignoredProperty) {
242*1c2bbba8SAndroid Build Coastguard Worker    IgnoreExample ie = new AutoValue_IgnoreExample(normalProperty);
243*1c2bbba8SAndroid Build Coastguard Worker    ie.ignoredProperty.set(ignoredProperty);
244*1c2bbba8SAndroid Build Coastguard Worker    return ie;
245*1c2bbba8SAndroid Build Coastguard Worker  }
246*1c2bbba8SAndroid Build Coastguard Worker
247*1c2bbba8SAndroid Build Coastguard Worker  abstract String normalProperty();
248*1c2bbba8SAndroid Build Coastguard Worker
249*1c2bbba8SAndroid Build Coastguard Worker  private final AtomicReference<String> ignoredProperty = new AtomicReference<>();
250*1c2bbba8SAndroid Build Coastguard Worker
251*1c2bbba8SAndroid Build Coastguard Worker  final String ignoredProperty() {
252*1c2bbba8SAndroid Build Coastguard Worker    return ignoredProperty.get();
253*1c2bbba8SAndroid Build Coastguard Worker  }
254*1c2bbba8SAndroid Build Coastguard Worker}
255*1c2bbba8SAndroid Build Coastguard Worker```
256*1c2bbba8SAndroid Build Coastguard Worker
257*1c2bbba8SAndroid Build Coastguard WorkerNote that this means the field is also ignored by `toString`; to AutoValue the
258*1c2bbba8SAndroid Build Coastguard Workerprivate field simply doesn't exist.
259*1c2bbba8SAndroid Build Coastguard Worker
260*1c2bbba8SAndroid Build Coastguard WorkerNote that we use `AtomicReference<String>` to ensure that other threads will
261*1c2bbba8SAndroid Build Coastguard Workercorrectly see the value that was written. You could also make the field
262*1c2bbba8SAndroid Build Coastguard Worker`volatile`, or use `synchronized` (`synchronized (ie)` around the assignment and
263*1c2bbba8SAndroid Build Coastguard Worker`synchronized` on the `ignoredProperty()` method).
264*1c2bbba8SAndroid Build Coastguard Worker
265*1c2bbba8SAndroid Build Coastguard Worker## <a name="supertypes"></a>... have AutoValue also implement abstract methods from my supertypes?
266*1c2bbba8SAndroid Build Coastguard Worker
267*1c2bbba8SAndroid Build Coastguard WorkerAutoValue will recognize every abstract accessor method whether it is defined
268*1c2bbba8SAndroid Build Coastguard Workerdirectly in your own hand-written class or in a supertype.
269*1c2bbba8SAndroid Build Coastguard Worker
270*1c2bbba8SAndroid Build Coastguard WorkerThese abstract methods can come from more than one place, for example from an
271*1c2bbba8SAndroid Build Coastguard Workerinterface and from the superclass. It may not then be obvious what order they
272*1c2bbba8SAndroid Build Coastguard Workerare in, even though you need to know this order if you want to call the
273*1c2bbba8SAndroid Build Coastguard Workergenerated `AutoValue_Foo` constructor. You might find it clearer to use a
274*1c2bbba8SAndroid Build Coastguard Worker[builder](builders.md) instead. But the order is deterministic: within a class
275*1c2bbba8SAndroid Build Coastguard Workeror interface, methods are in the order they appear in the source code; methods
276*1c2bbba8SAndroid Build Coastguard Workerin ancestors come before methods in descendants; methods in interfaces come
277*1c2bbba8SAndroid Build Coastguard Workerbefore methods in classes; and in a class or interface that has more than one
278*1c2bbba8SAndroid Build Coastguard Workersuperinterface, the interfaces are in the order of their appearance in
279*1c2bbba8SAndroid Build Coastguard Worker`implements` or `extends`.
280*1c2bbba8SAndroid Build Coastguard Worker
281*1c2bbba8SAndroid Build Coastguard Worker## <a name="generic"></a>... use AutoValue with a generic class?
282*1c2bbba8SAndroid Build Coastguard Worker
283*1c2bbba8SAndroid Build Coastguard WorkerThere's nothing to it: just add type parameters to your class and to your call
284*1c2bbba8SAndroid Build Coastguard Workerto the generated constructor.
285*1c2bbba8SAndroid Build Coastguard Worker
286*1c2bbba8SAndroid Build Coastguard Worker## <a name="serialize"></a>... make my class Java- or GWT\-serializable?
287*1c2bbba8SAndroid Build Coastguard Worker
288*1c2bbba8SAndroid Build Coastguard WorkerJust add `implements Serializable` or the `@GwtCompatible(serializable = true)`
289*1c2bbba8SAndroid Build Coastguard Workerannotation (respectively) to your hand-written class; it (as well as any
290*1c2bbba8SAndroid Build Coastguard Worker`serialVersionUID`) will be duplicated on the generated class, and you'll be
291*1c2bbba8SAndroid Build Coastguard Workergood to go.
292*1c2bbba8SAndroid Build Coastguard Worker
293*1c2bbba8SAndroid Build Coastguard Worker## <a name="annotation"></a>... use AutoValue to implement an annotation type?
294*1c2bbba8SAndroid Build Coastguard Worker
295*1c2bbba8SAndroid Build Coastguard WorkerNote: If you are writing your annotation in Kotlin, you don't need to use
296*1c2bbba8SAndroid Build Coastguard Worker`@AutoAnnotation`, since Kotlin allows you to instantiate annotations directly.
297*1c2bbba8SAndroid Build Coastguard Worker
298*1c2bbba8SAndroid Build Coastguard WorkerMost users should never have the need to programmatically create "fake"
299*1c2bbba8SAndroid Build Coastguard Workerannotation instances. But if you do, using `@AutoValue` in the usual way will
300*1c2bbba8SAndroid Build Coastguard Workerfail because the `Annotation.hashCode` specification is incompatible with
301*1c2bbba8SAndroid Build Coastguard WorkerAutoValue's behavior.
302*1c2bbba8SAndroid Build Coastguard Worker
303*1c2bbba8SAndroid Build Coastguard WorkerHowever, we've got you covered anyway! Suppose this annotation definition:
304*1c2bbba8SAndroid Build Coastguard Worker
305*1c2bbba8SAndroid Build Coastguard Worker```java
306*1c2bbba8SAndroid Build Coastguard Workerpublic @interface Named {
307*1c2bbba8SAndroid Build Coastguard Worker  String value();
308*1c2bbba8SAndroid Build Coastguard Worker}
309*1c2bbba8SAndroid Build Coastguard Worker```
310*1c2bbba8SAndroid Build Coastguard Worker
311*1c2bbba8SAndroid Build Coastguard WorkerAll you need is this:
312*1c2bbba8SAndroid Build Coastguard Worker
313*1c2bbba8SAndroid Build Coastguard Worker```java
314*1c2bbba8SAndroid Build Coastguard Workerpublic class Names {
315*1c2bbba8SAndroid Build Coastguard Worker  @AutoAnnotation public static Named named(String value) {
316*1c2bbba8SAndroid Build Coastguard Worker    return new AutoAnnotation_Names_named(value);
317*1c2bbba8SAndroid Build Coastguard Worker  }
318*1c2bbba8SAndroid Build Coastguard Worker}
319*1c2bbba8SAndroid Build Coastguard Worker```
320*1c2bbba8SAndroid Build Coastguard Worker
321*1c2bbba8SAndroid Build Coastguard WorkerIf your annotation has several elements, you may prefer to use `@AutoBuilder`:
322*1c2bbba8SAndroid Build Coastguard Worker
323*1c2bbba8SAndroid Build Coastguard Worker```java
324*1c2bbba8SAndroid Build Coastguard Workerpublic @interface Named {
325*1c2bbba8SAndroid Build Coastguard Worker  String value();
326*1c2bbba8SAndroid Build Coastguard Worker  int priority() default 0;
327*1c2bbba8SAndroid Build Coastguard Worker  int size() default 0;
328*1c2bbba8SAndroid Build Coastguard Worker}
329*1c2bbba8SAndroid Build Coastguard Worker
330*1c2bbba8SAndroid Build Coastguard Workerpublic class Names {
331*1c2bbba8SAndroid Build Coastguard Worker  @AutoBuilder(ofClass = Named.class)
332*1c2bbba8SAndroid Build Coastguard Worker  public interface NamedBuilder {
333*1c2bbba8SAndroid Build Coastguard Worker    NamedBuilder value(String x);
334*1c2bbba8SAndroid Build Coastguard Worker    NamedBuilder priority(int x);
335*1c2bbba8SAndroid Build Coastguard Worker    NamedBuilder size(int x);
336*1c2bbba8SAndroid Build Coastguard Worker    Named build();
337*1c2bbba8SAndroid Build Coastguard Worker  }
338*1c2bbba8SAndroid Build Coastguard Worker
339*1c2bbba8SAndroid Build Coastguard Worker  public static NamedBuilder namedBuilder() {
340*1c2bbba8SAndroid Build Coastguard Worker    return new AutoBuilder_Names_namedBuilder();
341*1c2bbba8SAndroid Build Coastguard Worker  }
342*1c2bbba8SAndroid Build Coastguard Worker
343*1c2bbba8SAndroid Build Coastguard Worker  ...
344*1c2bbba8SAndroid Build Coastguard Worker    Named named1 = namedBuilder().value("O'Cruiskeen").priority(17).size(23).build();
345*1c2bbba8SAndroid Build Coastguard Worker    Named named2 = namedBuilder().value("O'Cruiskeen").build();
346*1c2bbba8SAndroid Build Coastguard Worker    // priority and size get their default values
347*1c2bbba8SAndroid Build Coastguard Worker  ...
348*1c2bbba8SAndroid Build Coastguard Worker}
349*1c2bbba8SAndroid Build Coastguard Worker```
350*1c2bbba8SAndroid Build Coastguard Worker
351*1c2bbba8SAndroid Build Coastguard WorkerFor more details, see the [`AutoAnnotation`
352*1c2bbba8SAndroid Build Coastguard Workerjavadoc](http://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/AutoAnnotation.java#L24).
353*1c2bbba8SAndroid Build Coastguard Worker
354*1c2bbba8SAndroid Build Coastguard Worker## <a name="setters"></a>... also include setter (mutator) methods?
355*1c2bbba8SAndroid Build Coastguard Worker
356*1c2bbba8SAndroid Build Coastguard WorkerYou can't; AutoValue only generates immutable value classes.
357*1c2bbba8SAndroid Build Coastguard Worker
358*1c2bbba8SAndroid Build Coastguard WorkerNote that giving value semantics to a mutable type is widely considered a
359*1c2bbba8SAndroid Build Coastguard Workerquestionable practice in the first place. Equal instances of a value class are
360*1c2bbba8SAndroid Build Coastguard Workertreated as *interchangeable*, but they can't truly be interchangeable if one
361*1c2bbba8SAndroid Build Coastguard Workermight be mutated and the other not.
362*1c2bbba8SAndroid Build Coastguard Worker
363*1c2bbba8SAndroid Build Coastguard Worker## <a name="compareTo"></a>... also generate `compareTo`?
364*1c2bbba8SAndroid Build Coastguard Worker
365*1c2bbba8SAndroid Build Coastguard WorkerAutoValue intentionally does not provide this feature. It is better for you to
366*1c2bbba8SAndroid Build Coastguard Workerroll your own comparison logic using the new methods added to
367*1c2bbba8SAndroid Build Coastguard Worker[`Comparator`](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html)
368*1c2bbba8SAndroid Build Coastguard Workerin Java 8, or
369*1c2bbba8SAndroid Build Coastguard Worker[`ComparisonChain`](https://guava.dev/releases/snapshot/api/docs/com/google/common/collect/ComparisonChain.html)
370*1c2bbba8SAndroid Build Coastguard Workerfrom [Guava](http://github.com/google/guava).
371*1c2bbba8SAndroid Build Coastguard Worker
372*1c2bbba8SAndroid Build Coastguard WorkerSince these mechanisms are easy to use, require very little code, and give you
373*1c2bbba8SAndroid Build Coastguard Workerthe flexibility you need, there's really no way for AutoValue to improve on
374*1c2bbba8SAndroid Build Coastguard Workerthem!
375*1c2bbba8SAndroid Build Coastguard Worker
376*1c2bbba8SAndroid Build Coastguard Worker## <a name="primitive_array"></a>... use a primitive array for a property value?
377*1c2bbba8SAndroid Build Coastguard Worker
378*1c2bbba8SAndroid Build Coastguard WorkerGo right ahead! AutoValue will generate code that acts on the *values* stored
379*1c2bbba8SAndroid Build Coastguard Workerthe array, not the object identity of the array itself, which is (with virtual
380*1c2bbba8SAndroid Build Coastguard Workercertainty) what you want. Heed the warnings given above about [mutable
381*1c2bbba8SAndroid Build Coastguard Workerproperties](#mutable_property).
382*1c2bbba8SAndroid Build Coastguard Worker
383*1c2bbba8SAndroid Build Coastguard Worker## <a name="object_array"></a>... use an object array for a property value?
384*1c2bbba8SAndroid Build Coastguard Worker
385*1c2bbba8SAndroid Build Coastguard WorkerThis is not allowed. Object arrays are very badly-behaved and unlike primitive
386*1c2bbba8SAndroid Build Coastguard Workerarrays, they can be replaced with a proper `List` implementation for very little
387*1c2bbba8SAndroid Build Coastguard Workeradded cost.
388*1c2bbba8SAndroid Build Coastguard Worker
389*1c2bbba8SAndroid Build Coastguard WorkerIf it's important to accept an object array at construction time, refer to the
390*1c2bbba8SAndroid Build Coastguard Worker*first* example shown [here](#mutable_property).
391*1c2bbba8SAndroid Build Coastguard Worker
392*1c2bbba8SAndroid Build Coastguard Worker## <a name="inherit"></a>... have one `@AutoValue` class extend another?
393*1c2bbba8SAndroid Build Coastguard Worker
394*1c2bbba8SAndroid Build Coastguard WorkerThis ability is intentionally not supported, because there is no way to do it
395*1c2bbba8SAndroid Build Coastguard Workercorrectly. See *Effective Java, 2nd Edition* Item 8: "Obey the general contract
396*1c2bbba8SAndroid Build Coastguard Workerwhen overriding equals".
397*1c2bbba8SAndroid Build Coastguard Worker
398*1c2bbba8SAndroid Build Coastguard Worker## <a name="private_accessors"></a>... keep my accessor methods private?
399*1c2bbba8SAndroid Build Coastguard Worker
400*1c2bbba8SAndroid Build Coastguard WorkerWe're sorry. This is one of the rare and unfortunate restrictions AutoValue's
401*1c2bbba8SAndroid Build Coastguard Workerapproach places on your API. Your accessor methods don't have to be *public*,
402*1c2bbba8SAndroid Build Coastguard Workerbut they must be at least package-visible.
403*1c2bbba8SAndroid Build Coastguard Worker
404*1c2bbba8SAndroid Build Coastguard Worker## <a name="public_constructor"></a>... expose a constructor, not factory method, as my public creation API?
405*1c2bbba8SAndroid Build Coastguard Worker
406*1c2bbba8SAndroid Build Coastguard WorkerWe're sorry. This is one of the rare restrictions AutoValue's approach places on
407*1c2bbba8SAndroid Build Coastguard Workeryour API. However, note that static factory methods are recommended over public
408*1c2bbba8SAndroid Build Coastguard Workerconstructors by *Effective Java*, Item 1.
409*1c2bbba8SAndroid Build Coastguard Worker
410*1c2bbba8SAndroid Build Coastguard Worker## <a name="interface"></a>... use AutoValue on an interface, not abstract class?
411*1c2bbba8SAndroid Build Coastguard Worker
412*1c2bbba8SAndroid Build Coastguard WorkerAutoValue classes can certainly implement an interface, however an interface may
413*1c2bbba8SAndroid Build Coastguard Workernot be used in lieu of an abstract class. The only advantage of interfaces we're
414*1c2bbba8SAndroid Build Coastguard Workeraware of is that you can omit `public abstract` from the methods. That's not
415*1c2bbba8SAndroid Build Coastguard Workermuch. On the other hand, you would lose the immutability guarantee, and you'd
416*1c2bbba8SAndroid Build Coastguard Workeralso invite more of the kind of bad behavior described in
417*1c2bbba8SAndroid Build Coastguard Worker[this best-practices item](practices.md#simple). On balance, we don't think it's
418*1c2bbba8SAndroid Build Coastguard Workerworth it.
419*1c2bbba8SAndroid Build Coastguard Worker
420*1c2bbba8SAndroid Build Coastguard Worker## <a name="memoize"></a>... memoize ("cache") derived properties?
421*1c2bbba8SAndroid Build Coastguard Worker
422*1c2bbba8SAndroid Build Coastguard WorkerSometimes your class has properties that are derived from the ones that
423*1c2bbba8SAndroid Build Coastguard WorkerAutoValue implements. You'd typically implement them with a concrete method that
424*1c2bbba8SAndroid Build Coastguard Workeruses the other properties:
425*1c2bbba8SAndroid Build Coastguard Worker
426*1c2bbba8SAndroid Build Coastguard Worker```java
427*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
428*1c2bbba8SAndroid Build Coastguard Workerabstract class Foo {
429*1c2bbba8SAndroid Build Coastguard Worker  abstract Bar barProperty();
430*1c2bbba8SAndroid Build Coastguard Worker
431*1c2bbba8SAndroid Build Coastguard Worker  String derivedProperty() {
432*1c2bbba8SAndroid Build Coastguard Worker    return someFunctionOf(barProperty());
433*1c2bbba8SAndroid Build Coastguard Worker  }
434*1c2bbba8SAndroid Build Coastguard Worker}
435*1c2bbba8SAndroid Build Coastguard Worker```
436*1c2bbba8SAndroid Build Coastguard Worker
437*1c2bbba8SAndroid Build Coastguard WorkerBut what if `someFunctionOf(Bar)` is expensive? You'd like to calculate it only
438*1c2bbba8SAndroid Build Coastguard Workerone time, then cache and reuse that value for all future calls. Normally,
439*1c2bbba8SAndroid Build Coastguard Workerthread-safe lazy initialization involves a lot of tricky boilerplate.
440*1c2bbba8SAndroid Build Coastguard Worker
441*1c2bbba8SAndroid Build Coastguard WorkerInstead, just write the derived-property accessor method as above, and
442*1c2bbba8SAndroid Build Coastguard Workerannotate it with [`@Memoized`]. Then AutoValue will override that method to
443*1c2bbba8SAndroid Build Coastguard Workerreturn a stored value after the first call:
444*1c2bbba8SAndroid Build Coastguard Worker
445*1c2bbba8SAndroid Build Coastguard Worker```java
446*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
447*1c2bbba8SAndroid Build Coastguard Workerabstract class Foo {
448*1c2bbba8SAndroid Build Coastguard Worker  abstract Bar barProperty();
449*1c2bbba8SAndroid Build Coastguard Worker
450*1c2bbba8SAndroid Build Coastguard Worker  @Memoized
451*1c2bbba8SAndroid Build Coastguard Worker  String derivedProperty() {
452*1c2bbba8SAndroid Build Coastguard Worker    return someFunctionOf(barProperty());
453*1c2bbba8SAndroid Build Coastguard Worker  }
454*1c2bbba8SAndroid Build Coastguard Worker}
455*1c2bbba8SAndroid Build Coastguard Worker```
456*1c2bbba8SAndroid Build Coastguard Worker
457*1c2bbba8SAndroid Build Coastguard WorkerThen your method will be called at most once, even if multiple threads attempt
458*1c2bbba8SAndroid Build Coastguard Workerto access the property concurrently.
459*1c2bbba8SAndroid Build Coastguard Worker
460*1c2bbba8SAndroid Build Coastguard WorkerThe annotated method must have the usual form of an accessor method, and may not
461*1c2bbba8SAndroid Build Coastguard Workerbe `abstract`, `final`, or `private`.
462*1c2bbba8SAndroid Build Coastguard Worker
463*1c2bbba8SAndroid Build Coastguard WorkerThe stored value will not be used in the implementation of `equals`, `hashCode`,
464*1c2bbba8SAndroid Build Coastguard Workeror `toString`.
465*1c2bbba8SAndroid Build Coastguard Worker
466*1c2bbba8SAndroid Build Coastguard WorkerIf a `@Memoized` method is also annotated with `@Nullable`, then `null` values
467*1c2bbba8SAndroid Build Coastguard Workerwill be stored; if not, then the overriding method throws `NullPointerException`
468*1c2bbba8SAndroid Build Coastguard Workerwhen the annotated method returns `null`.
469*1c2bbba8SAndroid Build Coastguard Worker
470*1c2bbba8SAndroid Build Coastguard Worker[`@Memoized`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/memoized/Memoized.java
471*1c2bbba8SAndroid Build Coastguard Worker
472*1c2bbba8SAndroid Build Coastguard Worker## <a name="memoize_hash_tostring"></a>... memoize the result of `hashCode` or `toString`?
473*1c2bbba8SAndroid Build Coastguard Worker
474*1c2bbba8SAndroid Build Coastguard WorkerYou can also make your class remember and reuse the result of `hashCode`,
475*1c2bbba8SAndroid Build Coastguard Worker`toString`, or both, like this:
476*1c2bbba8SAndroid Build Coastguard Worker
477*1c2bbba8SAndroid Build Coastguard Worker```java
478*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
479*1c2bbba8SAndroid Build Coastguard Workerabstract class Foo {
480*1c2bbba8SAndroid Build Coastguard Worker  abstract Bar barProperty();
481*1c2bbba8SAndroid Build Coastguard Worker
482*1c2bbba8SAndroid Build Coastguard Worker  @Memoized
483*1c2bbba8SAndroid Build Coastguard Worker  @Override
484*1c2bbba8SAndroid Build Coastguard Worker  public abstract int hashCode();
485*1c2bbba8SAndroid Build Coastguard Worker
486*1c2bbba8SAndroid Build Coastguard Worker  @Memoized
487*1c2bbba8SAndroid Build Coastguard Worker  @Override
488*1c2bbba8SAndroid Build Coastguard Worker  public abstract String toString();
489*1c2bbba8SAndroid Build Coastguard Worker}
490*1c2bbba8SAndroid Build Coastguard Worker```
491*1c2bbba8SAndroid Build Coastguard Worker
492*1c2bbba8SAndroid Build Coastguard Worker## <a name="oneof"></a>... make a class where only one of its properties is ever set?
493*1c2bbba8SAndroid Build Coastguard Worker
494*1c2bbba8SAndroid Build Coastguard WorkerOften, the best way to do this is using inheritance. Although one
495*1c2bbba8SAndroid Build Coastguard Worker`@AutoValue` class can't inherit from another, two `@AutoValue` classes can
496*1c2bbba8SAndroid Build Coastguard Workerinherit from a common parent.
497*1c2bbba8SAndroid Build Coastguard Worker
498*1c2bbba8SAndroid Build Coastguard Worker```java
499*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class StringOrInteger {
500*1c2bbba8SAndroid Build Coastguard Worker  public abstract String representation();
501*1c2bbba8SAndroid Build Coastguard Worker
502*1c2bbba8SAndroid Build Coastguard Worker  public static StringOrInteger ofString(String s) {
503*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_StringOrInteger_StringValue(s);
504*1c2bbba8SAndroid Build Coastguard Worker  }
505*1c2bbba8SAndroid Build Coastguard Worker
506*1c2bbba8SAndroid Build Coastguard Worker  public static StringOrInteger ofInteger(int i) {
507*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_StringOrInteger_IntegerValue(i);
508*1c2bbba8SAndroid Build Coastguard Worker  }
509*1c2bbba8SAndroid Build Coastguard Worker
510*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue
511*1c2bbba8SAndroid Build Coastguard Worker  abstract static class StringValue extends StringOrInteger {
512*1c2bbba8SAndroid Build Coastguard Worker    abstract String string();
513*1c2bbba8SAndroid Build Coastguard Worker
514*1c2bbba8SAndroid Build Coastguard Worker    @Override
515*1c2bbba8SAndroid Build Coastguard Worker    public String representation() {
516*1c2bbba8SAndroid Build Coastguard Worker      return '"' + string() + '"';
517*1c2bbba8SAndroid Build Coastguard Worker    }
518*1c2bbba8SAndroid Build Coastguard Worker  }
519*1c2bbba8SAndroid Build Coastguard Worker
520*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue
521*1c2bbba8SAndroid Build Coastguard Worker  abstract static class IntegerValue extends StringOrInteger {
522*1c2bbba8SAndroid Build Coastguard Worker    abstract int integer();
523*1c2bbba8SAndroid Build Coastguard Worker
524*1c2bbba8SAndroid Build Coastguard Worker    @Override
525*1c2bbba8SAndroid Build Coastguard Worker    public String representation() {
526*1c2bbba8SAndroid Build Coastguard Worker      return Integer.toString(integer());
527*1c2bbba8SAndroid Build Coastguard Worker    }
528*1c2bbba8SAndroid Build Coastguard Worker  }
529*1c2bbba8SAndroid Build Coastguard Worker}
530*1c2bbba8SAndroid Build Coastguard Worker```
531*1c2bbba8SAndroid Build Coastguard Worker
532*1c2bbba8SAndroid Build Coastguard WorkerSo any `StringOrInteger` instance is actually either a `StringValue` or an
533*1c2bbba8SAndroid Build Coastguard Worker`IntegerValue`. Clients only care about the `representation()` method, so they
534*1c2bbba8SAndroid Build Coastguard Workerdon't need to know which it is.
535*1c2bbba8SAndroid Build Coastguard Worker
536*1c2bbba8SAndroid Build Coastguard WorkerBut if clients of your class may want to take different actions depending on
537*1c2bbba8SAndroid Build Coastguard Workerwhich property is set, there is an alternative to `@AutoValue` called
538*1c2bbba8SAndroid Build Coastguard Worker`@AutoOneOf`. This effectively creates a
539*1c2bbba8SAndroid Build Coastguard Worker[*tagged union*](https://en.wikipedia.org/wiki/Tagged_union).
540*1c2bbba8SAndroid Build Coastguard WorkerHere is `StringOrInteger` written using `@AutoOneOf`, with the
541*1c2bbba8SAndroid Build Coastguard Worker`representation()` method moved to a separate client class:
542*1c2bbba8SAndroid Build Coastguard Worker
543*1c2bbba8SAndroid Build Coastguard Worker```java
544*1c2bbba8SAndroid Build Coastguard Worker@AutoOneOf(StringOrInteger.Kind.class)
545*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class StringOrInteger {
546*1c2bbba8SAndroid Build Coastguard Worker  public enum Kind {STRING, INTEGER}
547*1c2bbba8SAndroid Build Coastguard Worker  public abstract Kind getKind();
548*1c2bbba8SAndroid Build Coastguard Worker
549*1c2bbba8SAndroid Build Coastguard Worker  public abstract String string();
550*1c2bbba8SAndroid Build Coastguard Worker
551*1c2bbba8SAndroid Build Coastguard Worker  public abstract int integer();
552*1c2bbba8SAndroid Build Coastguard Worker
553*1c2bbba8SAndroid Build Coastguard Worker  public static StringOrInteger ofString(String s) {
554*1c2bbba8SAndroid Build Coastguard Worker    return AutoOneOf_StringOrInteger.string(s);
555*1c2bbba8SAndroid Build Coastguard Worker  }
556*1c2bbba8SAndroid Build Coastguard Worker
557*1c2bbba8SAndroid Build Coastguard Worker  public static StringOrInteger ofInteger(int i) {
558*1c2bbba8SAndroid Build Coastguard Worker    return AutoOneOf_StringOrInteger.integer(i);
559*1c2bbba8SAndroid Build Coastguard Worker  }
560*1c2bbba8SAndroid Build Coastguard Worker}
561*1c2bbba8SAndroid Build Coastguard Worker
562*1c2bbba8SAndroid Build Coastguard Workerpublic class Client {
563*1c2bbba8SAndroid Build Coastguard Worker  public String representation(StringOrInteger stringOrInteger) {
564*1c2bbba8SAndroid Build Coastguard Worker    switch (stringOrInteger.getKind()) {
565*1c2bbba8SAndroid Build Coastguard Worker      case STRING:
566*1c2bbba8SAndroid Build Coastguard Worker        return '"' + stringOrInteger.string() + '"';
567*1c2bbba8SAndroid Build Coastguard Worker      case INTEGER:
568*1c2bbba8SAndroid Build Coastguard Worker        return Integer.toString(stringOrInteger.integer());
569*1c2bbba8SAndroid Build Coastguard Worker    }
570*1c2bbba8SAndroid Build Coastguard Worker    throw new AssertionError(stringOrInteger.getKind());
571*1c2bbba8SAndroid Build Coastguard Worker  }
572*1c2bbba8SAndroid Build Coastguard Worker}
573*1c2bbba8SAndroid Build Coastguard Worker```
574*1c2bbba8SAndroid Build Coastguard Worker
575*1c2bbba8SAndroid Build Coastguard WorkerSwitching on an enum like this can lead to more robust code than using
576*1c2bbba8SAndroid Build Coastguard Worker`instanceof` checks, especially if a tool like [Error
577*1c2bbba8SAndroid Build Coastguard WorkerProne](https://errorprone.info/bugpattern/MissingCasesInEnumSwitch) can alert you
578*1c2bbba8SAndroid Build Coastguard Workerif you add a new variant without updating all your switches. (On the other hand,
579*1c2bbba8SAndroid Build Coastguard Workerif nothing outside your class references `getKind()`, you should consider if a
580*1c2bbba8SAndroid Build Coastguard Workersolution using inheritance might be better.)
581*1c2bbba8SAndroid Build Coastguard Worker
582*1c2bbba8SAndroid Build Coastguard WorkerThere must be an enum such as `Kind`, though it doesn't have to be called `Kind`
583*1c2bbba8SAndroid Build Coastguard Workerand it doesn't have to be nested inside the `@AutoOneOf` class. There must be an
584*1c2bbba8SAndroid Build Coastguard Workerabstract method returning the enum, though it doesn't have to be called
585*1c2bbba8SAndroid Build Coastguard Worker`getKind()`. For every value of the enum, there must be an abstract method with
586*1c2bbba8SAndroid Build Coastguard Workerthe same name (ignoring case and underscores). An `@AutoOneOf` class called
587*1c2bbba8SAndroid Build Coastguard Worker`Foo` will then get a generated class called `AutoOneOf_Foo` that has a static
588*1c2bbba8SAndroid Build Coastguard Workerfactory method for each property, with the same name. In the example, the
589*1c2bbba8SAndroid Build Coastguard Worker`STRING` value in the enum corresponds to the `string()` property and to the
590*1c2bbba8SAndroid Build Coastguard Worker`AutoOneOf_StringOrInteger.string` factory method.
591*1c2bbba8SAndroid Build Coastguard Worker
592*1c2bbba8SAndroid Build Coastguard WorkerProperties in an `@AutoOneOf` class can be `void` to indicate that the
593*1c2bbba8SAndroid Build Coastguard Workercorresponding variant has no data. In that case, the factory method for that
594*1c2bbba8SAndroid Build Coastguard Workervariant has no parameters:
595*1c2bbba8SAndroid Build Coastguard Worker
596*1c2bbba8SAndroid Build Coastguard Worker```java
597*1c2bbba8SAndroid Build Coastguard Worker@AutoOneOf(Transform.Kind.class)
598*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Transform {
599*1c2bbba8SAndroid Build Coastguard Worker  public enum Kind {NONE, CIRCLE_CROP, BLUR}
600*1c2bbba8SAndroid Build Coastguard Worker  public abstract Kind getKind();
601*1c2bbba8SAndroid Build Coastguard Worker
602*1c2bbba8SAndroid Build Coastguard Worker  abstract void none();
603*1c2bbba8SAndroid Build Coastguard Worker
604*1c2bbba8SAndroid Build Coastguard Worker  abstract void circleCrop();
605*1c2bbba8SAndroid Build Coastguard Worker
606*1c2bbba8SAndroid Build Coastguard Worker  public abstract BlurTransformParameters blur();
607*1c2bbba8SAndroid Build Coastguard Worker
608*1c2bbba8SAndroid Build Coastguard Worker  public static Transform ofNone() {
609*1c2bbba8SAndroid Build Coastguard Worker    return AutoOneOf_Transform.none();
610*1c2bbba8SAndroid Build Coastguard Worker  }
611*1c2bbba8SAndroid Build Coastguard Worker
612*1c2bbba8SAndroid Build Coastguard Worker  public static Transform ofCircleCrop() {
613*1c2bbba8SAndroid Build Coastguard Worker    return AutoOneOf_Transform.circleCrop();
614*1c2bbba8SAndroid Build Coastguard Worker  }
615*1c2bbba8SAndroid Build Coastguard Worker
616*1c2bbba8SAndroid Build Coastguard Worker  public static Transform ofBlur(BlurTransformParmeters params) {
617*1c2bbba8SAndroid Build Coastguard Worker    return AutoOneOf_Transform.blur(params);
618*1c2bbba8SAndroid Build Coastguard Worker  }
619*1c2bbba8SAndroid Build Coastguard Worker}
620*1c2bbba8SAndroid Build Coastguard Worker```
621*1c2bbba8SAndroid Build Coastguard Worker
622*1c2bbba8SAndroid Build Coastguard WorkerHere, the `NONE` and `CIRCLE_CROP` variants have no associated data but are
623*1c2bbba8SAndroid Build Coastguard Workerdistinct from each other. The `BLUR` variant does have data. The `none()`
624*1c2bbba8SAndroid Build Coastguard Workerand `circleCrop()` methods are package-private; they must exist to configure
625*1c2bbba8SAndroid Build Coastguard Worker`@AutoOneOf`, but calling them is not very useful. (It does nothing if the
626*1c2bbba8SAndroid Build Coastguard Workerinstance is of the correct variant, or throws an exception otherwise.)
627*1c2bbba8SAndroid Build Coastguard Worker
628*1c2bbba8SAndroid Build Coastguard WorkerThe `AutoOneOf_Transform.none()` and `AutoOneOf_Transform.circleCrop()` methods
629*1c2bbba8SAndroid Build Coastguard Workerreturn the same instance every time they are called.
630*1c2bbba8SAndroid Build Coastguard Worker
631*1c2bbba8SAndroid Build Coastguard WorkerIf one of the `void` variants means "none", consider using an `Optional<Transform>` or
632*1c2bbba8SAndroid Build Coastguard Workera `@Nullable Transform` instead of that variant.
633*1c2bbba8SAndroid Build Coastguard Worker
634*1c2bbba8SAndroid Build Coastguard WorkerProperties in an `@AutoOneOf` class cannot be null. Instead of a
635*1c2bbba8SAndroid Build Coastguard Worker`StringOrInteger` with a `@Nullable String`, you probably want a
636*1c2bbba8SAndroid Build Coastguard Worker`@Nullable StringOrInteger` or an `Optional<StringOrInteger>`, or an empty
637*1c2bbba8SAndroid Build Coastguard Workervariant as just described.
638*1c2bbba8SAndroid Build Coastguard Worker
639*1c2bbba8SAndroid Build Coastguard Worker## <a name="copy_annotations"></a>... copy annotations from a class/method to the implemented class/method/field?
640*1c2bbba8SAndroid Build Coastguard Worker
641*1c2bbba8SAndroid Build Coastguard Worker### Copying to the generated class
642*1c2bbba8SAndroid Build Coastguard Worker
643*1c2bbba8SAndroid Build Coastguard WorkerIf you want to copy annotations from your `@AutoValue`-annotated class to the
644*1c2bbba8SAndroid Build Coastguard Workergenerated `AutoValue_...` implementation, annotate your class with
645*1c2bbba8SAndroid Build Coastguard Worker[`@AutoValue.CopyAnnotations`].
646*1c2bbba8SAndroid Build Coastguard Worker
647*1c2bbba8SAndroid Build Coastguard WorkerFor example, if `Example.java` is:
648*1c2bbba8SAndroid Build Coastguard Worker
649*1c2bbba8SAndroid Build Coastguard Worker```java
650*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
651*1c2bbba8SAndroid Build Coastguard Worker@AutoValue.CopyAnnotations
652*1c2bbba8SAndroid Build Coastguard Worker@SuppressWarnings("Immutable") // justification ...
653*1c2bbba8SAndroid Build Coastguard Workerabstract class Example {
654*1c2bbba8SAndroid Build Coastguard Worker  // details ...
655*1c2bbba8SAndroid Build Coastguard Worker}
656*1c2bbba8SAndroid Build Coastguard Worker```
657*1c2bbba8SAndroid Build Coastguard Worker
658*1c2bbba8SAndroid Build Coastguard WorkerThen `@AutoValue` will generate `AutoValue_Example.java`:
659*1c2bbba8SAndroid Build Coastguard Worker
660*1c2bbba8SAndroid Build Coastguard Worker```java
661*1c2bbba8SAndroid Build Coastguard Worker@SuppressWarnings("Immutable")
662*1c2bbba8SAndroid Build Coastguard Workerfinal class AutoValue_Example extends Example {
663*1c2bbba8SAndroid Build Coastguard Worker  // implementation ...
664*1c2bbba8SAndroid Build Coastguard Worker}
665*1c2bbba8SAndroid Build Coastguard Worker```
666*1c2bbba8SAndroid Build Coastguard Worker
667*1c2bbba8SAndroid Build Coastguard WorkerApplying `@AutoValue.CopyAnnotations` to an `@AutoValue.Builder` class like
668*1c2bbba8SAndroid Build Coastguard Worker`Foo.Builder` similarly causes annotations on that class to be copied to the
669*1c2bbba8SAndroid Build Coastguard Workergenerated subclass `AutoValue_Foo.Builder`.
670*1c2bbba8SAndroid Build Coastguard Worker
671*1c2bbba8SAndroid Build Coastguard Worker### Copying to the generated method
672*1c2bbba8SAndroid Build Coastguard Worker
673*1c2bbba8SAndroid Build Coastguard WorkerFor historical reasons, annotations on methods of an `@AutoValue`-annotated
674*1c2bbba8SAndroid Build Coastguard Workerclass are copied to the generated implementation class's methods. However, if
675*1c2bbba8SAndroid Build Coastguard Workeryou want to exclude some annotations from being copied, you can use
676*1c2bbba8SAndroid Build Coastguard Worker[`@AutoValue.CopyAnnotations`]'s `exclude` method to stop this behavior.
677*1c2bbba8SAndroid Build Coastguard Worker
678*1c2bbba8SAndroid Build Coastguard Worker### Copying to the generated field
679*1c2bbba8SAndroid Build Coastguard Worker
680*1c2bbba8SAndroid Build Coastguard WorkerIf you want to copy annotations from your `@AutoValue`-annotated class's methods
681*1c2bbba8SAndroid Build Coastguard Workerto the generated fields in the `AutoValue_...` implementation, annotate your
682*1c2bbba8SAndroid Build Coastguard Workermethod with [`@AutoValue.CopyAnnotations`].
683*1c2bbba8SAndroid Build Coastguard Worker
684*1c2bbba8SAndroid Build Coastguard WorkerFor example, if `Example.java` is:
685*1c2bbba8SAndroid Build Coastguard Worker
686*1c2bbba8SAndroid Build Coastguard Worker```java
687*1c2bbba8SAndroid Build Coastguard Worker@Immutable
688*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
689*1c2bbba8SAndroid Build Coastguard Workerabstract class Example {
690*1c2bbba8SAndroid Build Coastguard Worker  @CopyAnnotations
691*1c2bbba8SAndroid Build Coastguard Worker  @SuppressWarnings("Immutable") // justification ...
692*1c2bbba8SAndroid Build Coastguard Worker  abstract Object getObject();
693*1c2bbba8SAndroid Build Coastguard Worker
694*1c2bbba8SAndroid Build Coastguard Worker  // other details ...
695*1c2bbba8SAndroid Build Coastguard Worker}
696*1c2bbba8SAndroid Build Coastguard Worker```
697*1c2bbba8SAndroid Build Coastguard Worker
698*1c2bbba8SAndroid Build Coastguard WorkerThen `@AutoValue` will generate `AutoValue_Example.java`:
699*1c2bbba8SAndroid Build Coastguard Worker
700*1c2bbba8SAndroid Build Coastguard Worker```java
701*1c2bbba8SAndroid Build Coastguard Workerfinal class AutoValue_Example extends Example {
702*1c2bbba8SAndroid Build Coastguard Worker  @SuppressWarnings("Immutable")
703*1c2bbba8SAndroid Build Coastguard Worker  private final Object object;
704*1c2bbba8SAndroid Build Coastguard Worker
705*1c2bbba8SAndroid Build Coastguard Worker  @SuppressWarnings("Immutable")
706*1c2bbba8SAndroid Build Coastguard Worker  @Override
707*1c2bbba8SAndroid Build Coastguard Worker  Object getObject() {
708*1c2bbba8SAndroid Build Coastguard Worker    return object;
709*1c2bbba8SAndroid Build Coastguard Worker  }
710*1c2bbba8SAndroid Build Coastguard Worker
711*1c2bbba8SAndroid Build Coastguard Worker  // other details ...
712*1c2bbba8SAndroid Build Coastguard Worker}
713*1c2bbba8SAndroid Build Coastguard Worker```
714*1c2bbba8SAndroid Build Coastguard Worker
715*1c2bbba8SAndroid Build Coastguard Worker[`@AutoValue.CopyAnnotations`]: http://static.javadoc.io/com.google.auto.value/auto-value/1.6/com/google/auto/value/AutoValue.CopyAnnotations.html
716*1c2bbba8SAndroid Build Coastguard Worker
717*1c2bbba8SAndroid Build Coastguard Worker## <a name="toprettystring"></a>... create a pretty string representation?
718*1c2bbba8SAndroid Build Coastguard Worker
719*1c2bbba8SAndroid Build Coastguard WorkerIf you have a value class with a long `toString()` representation, annotate a
720*1c2bbba8SAndroid Build Coastguard Workermethod with [`@ToPrettyString`] and AutoValue will generate an implementation that
721*1c2bbba8SAndroid Build Coastguard Workerreturns a pretty String rendering of the instance. For example:
722*1c2bbba8SAndroid Build Coastguard Worker
723*1c2bbba8SAndroid Build Coastguard Worker```java
724*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
725*1c2bbba8SAndroid Build Coastguard Workerabstract class Song {
726*1c2bbba8SAndroid Build Coastguard Worker  abstract String lyrics();
727*1c2bbba8SAndroid Build Coastguard Worker  abstract List<Artist> artists();
728*1c2bbba8SAndroid Build Coastguard Worker
729*1c2bbba8SAndroid Build Coastguard Worker  @ToPrettyString
730*1c2bbba8SAndroid Build Coastguard Worker  abstract String toPrettyString();
731*1c2bbba8SAndroid Build Coastguard Worker}
732*1c2bbba8SAndroid Build Coastguard Worker```
733*1c2bbba8SAndroid Build Coastguard Worker
734*1c2bbba8SAndroid Build Coastguard WorkerBelow is a sample rendering of the result of calling `toPrettyString()`.
735*1c2bbba8SAndroid Build Coastguard Worker
736*1c2bbba8SAndroid Build Coastguard Worker```
737*1c2bbba8SAndroid Build Coastguard WorkerSong {
738*1c2bbba8SAndroid Build Coastguard Worker  lyrics = I'm off the deep end, watch as I dive in
739*1c2bbba8SAndroid Build Coastguard Worker    I'll never meet the ground
740*1c2bbba8SAndroid Build Coastguard Worker    Crash through the surface, where they can't hurt us
741*1c2bbba8SAndroid Build Coastguard Worker    We're far from the shallow now.,
742*1c2bbba8SAndroid Build Coastguard Worker  artists = [
743*1c2bbba8SAndroid Build Coastguard Worker    Artist {
744*1c2bbba8SAndroid Build Coastguard Worker      name = Lady Gaga,
745*1c2bbba8SAndroid Build Coastguard Worker    },
746*1c2bbba8SAndroid Build Coastguard Worker    Artist {
747*1c2bbba8SAndroid Build Coastguard Worker      name = Bradley Cooper,
748*1c2bbba8SAndroid Build Coastguard Worker    }
749*1c2bbba8SAndroid Build Coastguard Worker  ],
750*1c2bbba8SAndroid Build Coastguard Worker}
751*1c2bbba8SAndroid Build Coastguard Worker```
752*1c2bbba8SAndroid Build Coastguard Worker
753*1c2bbba8SAndroid Build Coastguard Worker`@ToPrettyString` can be used on the default `toString()` to override the
754*1c2bbba8SAndroid Build Coastguard Workerdefault AutoValue-generated `toString()` implementation, or on another
755*1c2bbba8SAndroid Build Coastguard Workeruser-defined method.
756*1c2bbba8SAndroid Build Coastguard Worker
757*1c2bbba8SAndroid Build Coastguard Worker[`@ToPrettyString`]: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/toprettystring/ToPrettyString.java
758