xref: /aosp_15_r20/external/auto/value/userguide/builders.md (revision 1c2bbba85eccddce6de79cbbf1645fda32e723f0)
1*1c2bbba8SAndroid Build Coastguard Worker# AutoValue with Builders
2*1c2bbba8SAndroid Build Coastguard Worker
3*1c2bbba8SAndroid Build Coastguard Worker
4*1c2bbba8SAndroid Build Coastguard WorkerThe [introduction](index.md) of this User Guide covers the basic usage of
5*1c2bbba8SAndroid Build Coastguard WorkerAutoValue using a static factory method as your public creation API. But in many
6*1c2bbba8SAndroid Build Coastguard Workercircumstances (such as those laid out in *Effective Java, 2nd Edition* Item 2),
7*1c2bbba8SAndroid Build Coastguard Workeryou may prefer to let your callers use a *builder* instead.
8*1c2bbba8SAndroid Build Coastguard Worker
9*1c2bbba8SAndroid Build Coastguard WorkerFortunately, AutoValue can generate builder classes too! This page explains how.
10*1c2bbba8SAndroid Build Coastguard WorkerNote that we recommend reading and understanding the basic usage shown in the
11*1c2bbba8SAndroid Build Coastguard Worker[introduction](index.md) first.
12*1c2bbba8SAndroid Build Coastguard Worker
13*1c2bbba8SAndroid Build Coastguard Worker## How to use AutoValue with Builders <a name="howto"></a>
14*1c2bbba8SAndroid Build Coastguard Worker
15*1c2bbba8SAndroid Build Coastguard WorkerAs explained in the introduction, the AutoValue concept is that **you write an
16*1c2bbba8SAndroid Build Coastguard Workerabstract value class, and AutoValue implements it**. Builder generation works in
17*1c2bbba8SAndroid Build Coastguard Workerthe exact same way: you also create an abstract builder class, nesting it inside
18*1c2bbba8SAndroid Build Coastguard Workeryour abstract value class, and AutoValue generates implementations for both.
19*1c2bbba8SAndroid Build Coastguard Worker
20*1c2bbba8SAndroid Build Coastguard Worker### In `Animal.java` <a name="example_java"></a>
21*1c2bbba8SAndroid Build Coastguard Worker
22*1c2bbba8SAndroid Build Coastguard Worker```java
23*1c2bbba8SAndroid Build Coastguard Workerimport com.google.auto.value.AutoValue;
24*1c2bbba8SAndroid Build Coastguard Worker
25*1c2bbba8SAndroid Build Coastguard Worker@AutoValue
26*1c2bbba8SAndroid Build Coastguard Workerabstract class Animal {
27*1c2bbba8SAndroid Build Coastguard Worker  abstract String name();
28*1c2bbba8SAndroid Build Coastguard Worker  abstract int numberOfLegs();
29*1c2bbba8SAndroid Build Coastguard Worker
30*1c2bbba8SAndroid Build Coastguard Worker  static Builder builder() {
31*1c2bbba8SAndroid Build Coastguard Worker    // The naming here will be different if you are using a nested class
32*1c2bbba8SAndroid Build Coastguard Worker    // e.g. `return new AutoValue_OuterClass_InnerClass.Builder();`
33*1c2bbba8SAndroid Build Coastguard Worker    return new AutoValue_Animal.Builder();
34*1c2bbba8SAndroid Build Coastguard Worker  }
35*1c2bbba8SAndroid Build Coastguard Worker
36*1c2bbba8SAndroid Build Coastguard Worker  @AutoValue.Builder
37*1c2bbba8SAndroid Build Coastguard Worker  abstract static class Builder {
38*1c2bbba8SAndroid Build Coastguard Worker    abstract Builder setName(String value);
39*1c2bbba8SAndroid Build Coastguard Worker    abstract Builder setNumberOfLegs(int value);
40*1c2bbba8SAndroid Build Coastguard Worker    abstract Animal build();
41*1c2bbba8SAndroid Build Coastguard Worker  }
42*1c2bbba8SAndroid Build Coastguard Worker}
43*1c2bbba8SAndroid Build Coastguard Worker```
44*1c2bbba8SAndroid Build Coastguard Worker
45*1c2bbba8SAndroid Build Coastguard WorkerNote that in real life, some classes and methods would presumably be public and
46*1c2bbba8SAndroid Build Coastguard Workerhave **Javadoc**. We're leaving these off in the User Guide only to keep the
47*1c2bbba8SAndroid Build Coastguard Workerexamples clean and short.
48*1c2bbba8SAndroid Build Coastguard Worker
49*1c2bbba8SAndroid Build Coastguard Worker### Usage <a name="usage"></a>
50*1c2bbba8SAndroid Build Coastguard Worker
51*1c2bbba8SAndroid Build Coastguard Worker```java
52*1c2bbba8SAndroid Build Coastguard Workerpublic void testAnimal() {
53*1c2bbba8SAndroid Build Coastguard Worker  Animal dog = Animal.builder().setName("dog").setNumberOfLegs(4).build();
54*1c2bbba8SAndroid Build Coastguard Worker  assertEquals("dog", dog.name());
55*1c2bbba8SAndroid Build Coastguard Worker  assertEquals(4, dog.numberOfLegs());
56*1c2bbba8SAndroid Build Coastguard Worker
57*1c2bbba8SAndroid Build Coastguard Worker  // You probably don't need to write assertions like these; just illustrating.
58*1c2bbba8SAndroid Build Coastguard Worker  assertTrue(
59*1c2bbba8SAndroid Build Coastguard Worker      Animal.builder().setName("dog").setNumberOfLegs(4).build().equals(dog));
60*1c2bbba8SAndroid Build Coastguard Worker  assertFalse(
61*1c2bbba8SAndroid Build Coastguard Worker      Animal.builder().setName("cat").setNumberOfLegs(4).build().equals(dog));
62*1c2bbba8SAndroid Build Coastguard Worker  assertFalse(
63*1c2bbba8SAndroid Build Coastguard Worker      Animal.builder().setName("dog").setNumberOfLegs(2).build().equals(dog));
64*1c2bbba8SAndroid Build Coastguard Worker
65*1c2bbba8SAndroid Build Coastguard Worker  assertEquals("Animal{name=dog, numberOfLegs=4}", dog.toString());
66*1c2bbba8SAndroid Build Coastguard Worker}
67*1c2bbba8SAndroid Build Coastguard Worker```
68*1c2bbba8SAndroid Build Coastguard Worker
69*1c2bbba8SAndroid Build Coastguard Worker### What does AutoValue generate? <a name="generated"></a>
70*1c2bbba8SAndroid Build Coastguard Worker
71*1c2bbba8SAndroid Build Coastguard WorkerFor the `Animal` example shown above, here is [typical code AutoValue might
72*1c2bbba8SAndroid Build Coastguard Workergenerate](generated-builder-example.md).
73*1c2bbba8SAndroid Build Coastguard Worker
74*1c2bbba8SAndroid Build Coastguard Worker## Warnings <a name="warnings"></a>
75*1c2bbba8SAndroid Build Coastguard Worker
76*1c2bbba8SAndroid Build Coastguard WorkerBe sure to put the static `builder()` method directly in your value class (e.g.,
77*1c2bbba8SAndroid Build Coastguard Worker`Animal`) and not the nested abstract `Builder` class. That ensures that the
78*1c2bbba8SAndroid Build Coastguard Worker`Animal` class is always initialized before `Builder`. Otherwise you may be
79*1c2bbba8SAndroid Build Coastguard Workerexposing yourself to initialization-order problems.
80*1c2bbba8SAndroid Build Coastguard Worker
81*1c2bbba8SAndroid Build Coastguard Worker## <a name="howto"></a>How do I...
82*1c2bbba8SAndroid Build Coastguard Worker
83*1c2bbba8SAndroid Build Coastguard Worker*   ... [use (or not use) `set` **prefixes**?](builders-howto.md#beans)
84*1c2bbba8SAndroid Build Coastguard Worker*   ... [use different **names** besides
85*1c2bbba8SAndroid Build Coastguard Worker    `builder()`/`Builder`/`build()`?](builders-howto.md#build_names)
86*1c2bbba8SAndroid Build Coastguard Worker*   ... [specify a **default** value for a property?](builders-howto.md#default)
87*1c2bbba8SAndroid Build Coastguard Worker*   ... [initialize a builder to the same property values as an **existing**
88*1c2bbba8SAndroid Build Coastguard Worker    value instance](builders-howto.md#to_builder)
89*1c2bbba8SAndroid Build Coastguard Worker*   ... [include `with-` methods on my value class for creating slightly
90*1c2bbba8SAndroid Build Coastguard Worker    **altered** instances?](builders-howto.md#withers)
91*1c2bbba8SAndroid Build Coastguard Worker*   ... [**validate** property values?](builders-howto.md#validate)
92*1c2bbba8SAndroid Build Coastguard Worker*   ... [**normalize** (modify) a property value at `build`
93*1c2bbba8SAndroid Build Coastguard Worker    time?](builders-howto.md#normalize)
94*1c2bbba8SAndroid Build Coastguard Worker*   ... [expose **both** a builder and a factory
95*1c2bbba8SAndroid Build Coastguard Worker    method?](builders-howto.md#both)
96*1c2bbba8SAndroid Build Coastguard Worker*   ... [handle `Optional` properties?](builders-howto.md#optional)
97*1c2bbba8SAndroid Build Coastguard Worker*   ... [use a **collection**-valued property?](builders-howto.md#collection)
98*1c2bbba8SAndroid Build Coastguard Worker    *   ... [let my builder **accumulate** values for a collection-valued
99*1c2bbba8SAndroid Build Coastguard Worker        property (not require them all at once)?](builders-howto.md#accumulate)
100*1c2bbba8SAndroid Build Coastguard Worker    *   ... [accumulate values for a collection-valued property, without
101*1c2bbba8SAndroid Build Coastguard Worker        **"breaking the chain"**?](builders-howto.md#add)
102*1c2bbba8SAndroid Build Coastguard Worker    *   ... [offer **both** accumulation and set-at-once methods for the same
103*1c2bbba8SAndroid Build Coastguard Worker        collection-valued property?](builders-howto.md#collection_both)
104*1c2bbba8SAndroid Build Coastguard Worker*   ... [access nested builders while
105*1c2bbba8SAndroid Build Coastguard Worker    building?](builders-howto.md#nested_builders)
106*1c2bbba8SAndroid Build Coastguard Worker*   ... [create a "step builder"?](builders-howto.md#step)
107*1c2bbba8SAndroid Build Coastguard Worker*   ... [create a builder for something other than an
108*1c2bbba8SAndroid Build Coastguard Worker    `@AutoValue`?](builders-howto.md#autobuilder)
109*1c2bbba8SAndroid Build Coastguard Worker*   ... [use a different build method for a
110*1c2bbba8SAndroid Build Coastguard Worker    property?](builders-howto.md#build_method)
111