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