1*1c2bbba8SAndroid Build Coastguard Worker# How do I... (Builder edition) 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 Worker**with the builder option**. You should read and understand [AutoValue with 6*1c2bbba8SAndroid Build Coastguard Workerbuilders](builders.md) first. 7*1c2bbba8SAndroid Build Coastguard Worker 8*1c2bbba8SAndroid Build Coastguard WorkerIf you are not using a builder, see [Introduction](index.md) and 9*1c2bbba8SAndroid Build Coastguard Worker[How do I...](howto.md) instead. 10*1c2bbba8SAndroid Build Coastguard Worker 11*1c2bbba8SAndroid Build Coastguard Worker## Contents 12*1c2bbba8SAndroid Build Coastguard Worker 13*1c2bbba8SAndroid Build Coastguard WorkerHow do I... 14*1c2bbba8SAndroid Build Coastguard Worker 15*1c2bbba8SAndroid Build Coastguard Worker* ... [use (or not use) `set` **prefixes**?](#beans) 16*1c2bbba8SAndroid Build Coastguard Worker* ... [use different **names** besides 17*1c2bbba8SAndroid Build Coastguard Worker `builder()`/`Builder`/`build()`?](#build_names) 18*1c2bbba8SAndroid Build Coastguard Worker* ... [specify a **default** value for a property?](#default) 19*1c2bbba8SAndroid Build Coastguard Worker* ... [initialize a builder to the same property values as an **existing** 20*1c2bbba8SAndroid Build Coastguard Worker value instance](#to_builder) 21*1c2bbba8SAndroid Build Coastguard Worker* ... [include `with-` methods on my value class for creating slightly 22*1c2bbba8SAndroid Build Coastguard Worker **altered** instances?](#withers) 23*1c2bbba8SAndroid Build Coastguard Worker* ... [**validate** property values?](#validate) 24*1c2bbba8SAndroid Build Coastguard Worker* ... [**normalize** (modify) a property value at `build` time?](#normalize) 25*1c2bbba8SAndroid Build Coastguard Worker* ... [expose **both** a builder and a factory method?](#both) 26*1c2bbba8SAndroid Build Coastguard Worker* ... [handle `Optional` properties?](#optional) 27*1c2bbba8SAndroid Build Coastguard Worker* ... [use a **collection**-valued property?](#collection) 28*1c2bbba8SAndroid Build Coastguard Worker * ... [let my builder **accumulate** values for a collection-valued 29*1c2bbba8SAndroid Build Coastguard Worker property (not require them all at once)?](#accumulate) 30*1c2bbba8SAndroid Build Coastguard Worker * ... [accumulate values for a collection-valued property, without 31*1c2bbba8SAndroid Build Coastguard Worker **"breaking the chain"**?](#add) 32*1c2bbba8SAndroid Build Coastguard Worker * ... [offer **both** accumulation and set-at-once methods for the same 33*1c2bbba8SAndroid Build Coastguard Worker collection-valued property?](#collection_both) 34*1c2bbba8SAndroid Build Coastguard Worker* ... [access nested builders while building?](#nested_builders) 35*1c2bbba8SAndroid Build Coastguard Worker* ... [create a "step builder"?](#step) 36*1c2bbba8SAndroid Build Coastguard Worker* ... [create a builder for something other than an `@AutoValue`?](#autobuilder) 37*1c2bbba8SAndroid Build Coastguard Worker* ... [use a different build method for a 38*1c2bbba8SAndroid Build Coastguard Worker property?](#build_method) 39*1c2bbba8SAndroid Build Coastguard Worker 40*1c2bbba8SAndroid Build Coastguard Worker## <a name="beans"></a>... use (or not use) `set` prefixes? 41*1c2bbba8SAndroid Build Coastguard Worker 42*1c2bbba8SAndroid Build Coastguard WorkerJust as you can choose whether to use JavaBeans-style names for property getters 43*1c2bbba8SAndroid Build Coastguard Worker(`getFoo()` or just `foo()`) in your value class, you have the same choice for 44*1c2bbba8SAndroid Build Coastguard Workersetters in builders too (`setFoo(value)` or just `foo(value)`). As with getters, 45*1c2bbba8SAndroid Build Coastguard Workeryou must use these prefixes consistently or not at all. 46*1c2bbba8SAndroid Build Coastguard Worker 47*1c2bbba8SAndroid Build Coastguard WorkerUsing `get`/`is` prefixes for getters and using the `set` prefix for setters are 48*1c2bbba8SAndroid Build Coastguard Workerindependent choices. For example, it is fine to use the `set` prefixes on all 49*1c2bbba8SAndroid Build Coastguard Workeryour builder methods, but omit the `get`/`is` prefixes from all your accessors. 50*1c2bbba8SAndroid Build Coastguard Worker 51*1c2bbba8SAndroid Build Coastguard WorkerHere is the `Animal` example using `get` prefixes but not `set` prefixes: 52*1c2bbba8SAndroid Build Coastguard Worker 53*1c2bbba8SAndroid Build Coastguard Worker```java 54*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 55*1c2bbba8SAndroid Build Coastguard Workerabstract class Animal { 56*1c2bbba8SAndroid Build Coastguard Worker abstract String getName(); 57*1c2bbba8SAndroid Build Coastguard Worker abstract int getNumberOfLegs(); 58*1c2bbba8SAndroid Build Coastguard Worker 59*1c2bbba8SAndroid Build Coastguard Worker static Builder builder() { 60*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 61*1c2bbba8SAndroid Build Coastguard Worker } 62*1c2bbba8SAndroid Build Coastguard Worker 63*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 64*1c2bbba8SAndroid Build Coastguard Worker abstract static class Builder { 65*1c2bbba8SAndroid Build Coastguard Worker abstract Builder name(String value); 66*1c2bbba8SAndroid Build Coastguard Worker abstract Builder numberOfLegs(int value); 67*1c2bbba8SAndroid Build Coastguard Worker abstract Animal build(); 68*1c2bbba8SAndroid Build Coastguard Worker } 69*1c2bbba8SAndroid Build Coastguard Worker} 70*1c2bbba8SAndroid Build Coastguard Worker``` 71*1c2bbba8SAndroid Build Coastguard Worker 72*1c2bbba8SAndroid Build Coastguard Worker## <a name="build_names"></a>... use different names besides `builder()`/`Builder`/`build()`? 73*1c2bbba8SAndroid Build Coastguard Worker 74*1c2bbba8SAndroid Build Coastguard WorkerUse whichever names you like; AutoValue doesn't actually care. 75*1c2bbba8SAndroid Build Coastguard Worker 76*1c2bbba8SAndroid Build Coastguard Worker(We would gently recommend these names as conventional.) 77*1c2bbba8SAndroid Build Coastguard Worker 78*1c2bbba8SAndroid Build Coastguard Worker## <a name="default"></a>... specify a default value for a property? 79*1c2bbba8SAndroid Build Coastguard Worker 80*1c2bbba8SAndroid Build Coastguard WorkerWhat should happen when a caller does not supply a value for a property before 81*1c2bbba8SAndroid Build Coastguard Workercalling `build()`? If the property in question is [nullable](howto.md#nullable), 82*1c2bbba8SAndroid Build Coastguard Workerit will simply default to `null` as you would expect. And if it is 83*1c2bbba8SAndroid Build Coastguard Worker[Optional](#optional) it will default to an empty `Optional` as you might also 84*1c2bbba8SAndroid Build Coastguard Workerexpect. But if it isn't either of those things (including if it is a 85*1c2bbba8SAndroid Build Coastguard Workerprimitive-valued property, which *can't* be null), then `build()` will throw an 86*1c2bbba8SAndroid Build Coastguard Workerunchecked exception. This includes collection properties, which must be given a 87*1c2bbba8SAndroid Build Coastguard Workervalue. They don't default to empty unless there is a 88*1c2bbba8SAndroid Build Coastguard Worker[collection builder](#accumulate). 89*1c2bbba8SAndroid Build Coastguard Worker 90*1c2bbba8SAndroid Build Coastguard WorkerBut this requirement to supply a value presents a problem, since one of the main 91*1c2bbba8SAndroid Build Coastguard Worker*advantages* of a builder in the first place is that callers can specify only 92*1c2bbba8SAndroid Build Coastguard Workerthe properties they care about! 93*1c2bbba8SAndroid Build Coastguard Worker 94*1c2bbba8SAndroid Build Coastguard WorkerThe solution is to provide a default value for such properties. Fortunately this 95*1c2bbba8SAndroid Build Coastguard Workeris easy: just set it on the newly-constructed builder instance before returning 96*1c2bbba8SAndroid Build Coastguard Workerit from the `builder()` method. 97*1c2bbba8SAndroid Build Coastguard Worker 98*1c2bbba8SAndroid Build Coastguard WorkerHere is the `Animal` example with the default number of legs being 4: 99*1c2bbba8SAndroid Build Coastguard Worker 100*1c2bbba8SAndroid Build Coastguard Worker```java 101*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 102*1c2bbba8SAndroid Build Coastguard Workerabstract class Animal { 103*1c2bbba8SAndroid Build Coastguard Worker abstract String name(); 104*1c2bbba8SAndroid Build Coastguard Worker abstract int numberOfLegs(); 105*1c2bbba8SAndroid Build Coastguard Worker 106*1c2bbba8SAndroid Build Coastguard Worker static Builder builder() { 107*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder() 108*1c2bbba8SAndroid Build Coastguard Worker .setNumberOfLegs(4); 109*1c2bbba8SAndroid Build Coastguard Worker } 110*1c2bbba8SAndroid Build Coastguard Worker 111*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 112*1c2bbba8SAndroid Build Coastguard Worker abstract static class Builder { 113*1c2bbba8SAndroid Build Coastguard Worker abstract Builder setName(String value); 114*1c2bbba8SAndroid Build Coastguard Worker abstract Builder setNumberOfLegs(int value); 115*1c2bbba8SAndroid Build Coastguard Worker abstract Animal build(); 116*1c2bbba8SAndroid Build Coastguard Worker } 117*1c2bbba8SAndroid Build Coastguard Worker} 118*1c2bbba8SAndroid Build Coastguard Worker``` 119*1c2bbba8SAndroid Build Coastguard Worker 120*1c2bbba8SAndroid Build Coastguard WorkerOccasionally you may want to supply a default value, but only if the property is 121*1c2bbba8SAndroid Build Coastguard Workernot set explicitly. This is covered in the section on 122*1c2bbba8SAndroid Build Coastguard Worker[normalization](#normalize). 123*1c2bbba8SAndroid Build Coastguard Worker 124*1c2bbba8SAndroid Build Coastguard Worker## <a name="to_builder"></a>... initialize a builder to the same property values as an existing value instance 125*1c2bbba8SAndroid Build Coastguard Worker 126*1c2bbba8SAndroid Build Coastguard WorkerSuppose your caller has an existing instance of your value class, and wants to 127*1c2bbba8SAndroid Build Coastguard Workerchange only one or two of its properties. Of course, it's immutable, but it 128*1c2bbba8SAndroid Build Coastguard Workerwould be convenient if they could easily get a `Builder` instance representing 129*1c2bbba8SAndroid Build Coastguard Workerthe same property values, which they could then modify and use to create a new 130*1c2bbba8SAndroid Build Coastguard Workervalue instance. 131*1c2bbba8SAndroid Build Coastguard Worker 132*1c2bbba8SAndroid Build Coastguard WorkerTo give them this ability, just add an abstract `toBuilder` method, returning 133*1c2bbba8SAndroid Build Coastguard Workeryour abstract builder type, to your value class. AutoValue will implement it. 134*1c2bbba8SAndroid Build Coastguard Worker 135*1c2bbba8SAndroid Build Coastguard Worker```java 136*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder toBuilder(); 137*1c2bbba8SAndroid Build Coastguard Worker``` 138*1c2bbba8SAndroid Build Coastguard Worker 139*1c2bbba8SAndroid Build Coastguard Worker## <a name="withers"></a>... include `with-` methods on my value class for creating slightly altered instances? 140*1c2bbba8SAndroid Build Coastguard Worker 141*1c2bbba8SAndroid Build Coastguard WorkerThis is a somewhat common pattern among immutable classes. You can't have 142*1c2bbba8SAndroid Build Coastguard Workersetters, but you can have methods that act similarly to setters by returning a 143*1c2bbba8SAndroid Build Coastguard Workernew immutable instance that has one property changed. 144*1c2bbba8SAndroid Build Coastguard Worker 145*1c2bbba8SAndroid Build Coastguard WorkerIf you're already using the builder option, you can add these methods by hand: 146*1c2bbba8SAndroid Build Coastguard Worker 147*1c2bbba8SAndroid Build Coastguard Worker```java 148*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 149*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 150*1c2bbba8SAndroid Build Coastguard Worker public abstract String name(); 151*1c2bbba8SAndroid Build Coastguard Worker public abstract int numberOfLegs(); 152*1c2bbba8SAndroid Build Coastguard Worker 153*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 154*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 155*1c2bbba8SAndroid Build Coastguard Worker } 156*1c2bbba8SAndroid Build Coastguard Worker 157*1c2bbba8SAndroid Build Coastguard Worker abstract Builder toBuilder(); 158*1c2bbba8SAndroid Build Coastguard Worker 159*1c2bbba8SAndroid Build Coastguard Worker public final Animal withName(String name) { 160*1c2bbba8SAndroid Build Coastguard Worker return toBuilder().setName(name).build(); 161*1c2bbba8SAndroid Build Coastguard Worker } 162*1c2bbba8SAndroid Build Coastguard Worker 163*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 164*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 165*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String value); 166*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setNumberOfLegs(int value); 167*1c2bbba8SAndroid Build Coastguard Worker public abstract Animal build(); 168*1c2bbba8SAndroid Build Coastguard Worker } 169*1c2bbba8SAndroid Build Coastguard Worker} 170*1c2bbba8SAndroid Build Coastguard Worker``` 171*1c2bbba8SAndroid Build Coastguard Worker 172*1c2bbba8SAndroid Build Coastguard WorkerNote that it's your free choice what to make public (`toBuilder`, `withName`, 173*1c2bbba8SAndroid Build Coastguard Workerneither, or both). 174*1c2bbba8SAndroid Build Coastguard Worker 175*1c2bbba8SAndroid Build Coastguard Worker## <a name="validate"></a>... validate property values? 176*1c2bbba8SAndroid Build Coastguard Worker 177*1c2bbba8SAndroid Build Coastguard WorkerValidating properties is a little less straightforward than it is in the 178*1c2bbba8SAndroid Build Coastguard Worker[non-builder case](howto.md#validate). 179*1c2bbba8SAndroid Build Coastguard Worker 180*1c2bbba8SAndroid Build Coastguard WorkerWhat you need to do is *split* your "build" method into two methods: 181*1c2bbba8SAndroid Build Coastguard Worker 182*1c2bbba8SAndroid Build Coastguard Worker* the non-visible, abstract method that AutoValue implements 183*1c2bbba8SAndroid Build Coastguard Worker* and the visible, *concrete* method you provide, which calls the generated 184*1c2bbba8SAndroid Build Coastguard Worker method and performs validation. 185*1c2bbba8SAndroid Build Coastguard Worker 186*1c2bbba8SAndroid Build Coastguard WorkerWe recommend naming these methods `autoBuild` and `build`, but any names will 187*1c2bbba8SAndroid Build Coastguard Workerwork. It ends up looking like this: 188*1c2bbba8SAndroid Build Coastguard Worker 189*1c2bbba8SAndroid Build Coastguard Worker```java 190*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 191*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 192*1c2bbba8SAndroid Build Coastguard Worker public abstract String name(); 193*1c2bbba8SAndroid Build Coastguard Worker public abstract int numberOfLegs(); 194*1c2bbba8SAndroid Build Coastguard Worker 195*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 196*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 197*1c2bbba8SAndroid Build Coastguard Worker } 198*1c2bbba8SAndroid Build Coastguard Worker 199*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 200*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 201*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String value); 202*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setNumberOfLegs(int value); 203*1c2bbba8SAndroid Build Coastguard Worker 204*1c2bbba8SAndroid Build Coastguard Worker abstract Animal autoBuild(); // not public 205*1c2bbba8SAndroid Build Coastguard Worker 206*1c2bbba8SAndroid Build Coastguard Worker public final Animal build() { 207*1c2bbba8SAndroid Build Coastguard Worker Animal animal = autoBuild(); 208*1c2bbba8SAndroid Build Coastguard Worker Preconditions.checkState(animal.numberOfLegs() >= 0, "Negative legs"); 209*1c2bbba8SAndroid Build Coastguard Worker return animal; 210*1c2bbba8SAndroid Build Coastguard Worker } 211*1c2bbba8SAndroid Build Coastguard Worker } 212*1c2bbba8SAndroid Build Coastguard Worker} 213*1c2bbba8SAndroid Build Coastguard Worker``` 214*1c2bbba8SAndroid Build Coastguard Worker 215*1c2bbba8SAndroid Build Coastguard Worker## <a name="normalize"></a>... normalize (modify) a property value at `build` time? 216*1c2bbba8SAndroid Build Coastguard Worker 217*1c2bbba8SAndroid Build Coastguard WorkerSuppose you want to convert the animal's name to lower case. 218*1c2bbba8SAndroid Build Coastguard Worker 219*1c2bbba8SAndroid Build Coastguard WorkerYou'll need to add a *getter* to your builder, as shown: 220*1c2bbba8SAndroid Build Coastguard Worker 221*1c2bbba8SAndroid Build Coastguard Worker```java 222*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 223*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 224*1c2bbba8SAndroid Build Coastguard Worker public abstract String name(); 225*1c2bbba8SAndroid Build Coastguard Worker public abstract int numberOfLegs(); 226*1c2bbba8SAndroid Build Coastguard Worker 227*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 228*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 229*1c2bbba8SAndroid Build Coastguard Worker } 230*1c2bbba8SAndroid Build Coastguard Worker 231*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 232*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 233*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String value); 234*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setNumberOfLegs(int value); 235*1c2bbba8SAndroid Build Coastguard Worker 236*1c2bbba8SAndroid Build Coastguard Worker abstract String name(); // must match method name in Animal 237*1c2bbba8SAndroid Build Coastguard Worker 238*1c2bbba8SAndroid Build Coastguard Worker abstract Animal autoBuild(); // not public 239*1c2bbba8SAndroid Build Coastguard Worker 240*1c2bbba8SAndroid Build Coastguard Worker public final Animal build() { 241*1c2bbba8SAndroid Build Coastguard Worker setName(name().toLowerCase()); 242*1c2bbba8SAndroid Build Coastguard Worker return autoBuild(); 243*1c2bbba8SAndroid Build Coastguard Worker } 244*1c2bbba8SAndroid Build Coastguard Worker } 245*1c2bbba8SAndroid Build Coastguard Worker} 246*1c2bbba8SAndroid Build Coastguard Worker``` 247*1c2bbba8SAndroid Build Coastguard Worker 248*1c2bbba8SAndroid Build Coastguard WorkerThe getter in your builder must have the same signature as the abstract property 249*1c2bbba8SAndroid Build Coastguard Workeraccessor method in the value class. It will return the value that has been set 250*1c2bbba8SAndroid Build Coastguard Workeron the `Builder`. If no value has been set for a 251*1c2bbba8SAndroid Build Coastguard Workernon-[nullable](howto.md#nullable) property, `IllegalStateException` is thrown. 252*1c2bbba8SAndroid Build Coastguard Worker 253*1c2bbba8SAndroid Build Coastguard WorkerGetters should generally only be used within the `Builder` as shown, so they are 254*1c2bbba8SAndroid Build Coastguard Workernot public. 255*1c2bbba8SAndroid Build Coastguard Worker 256*1c2bbba8SAndroid Build Coastguard Worker<p id="optional-getter">As an alternative to returning the same type as the 257*1c2bbba8SAndroid Build Coastguard Workerproperty accessor method, the builder getter can return an Optional wrapping of 258*1c2bbba8SAndroid Build Coastguard Workerthat type. This can be used if you want to supply a default, but only if the 259*1c2bbba8SAndroid Build Coastguard Workerproperty has not been set. (The [usual way](#default) of supplying defaults 260*1c2bbba8SAndroid Build Coastguard Workermeans that the property always appears to have been set.) For example, suppose 261*1c2bbba8SAndroid Build Coastguard Workeryou wanted the default name of your Animal to be something like "4-legged 262*1c2bbba8SAndroid Build Coastguard Workercreature", where 4 is the `numberOfLegs()` property. You might write this: 263*1c2bbba8SAndroid Build Coastguard Worker 264*1c2bbba8SAndroid Build Coastguard Worker```java 265*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 266*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 267*1c2bbba8SAndroid Build Coastguard Worker public abstract String name(); 268*1c2bbba8SAndroid Build Coastguard Worker public abstract int numberOfLegs(); 269*1c2bbba8SAndroid Build Coastguard Worker 270*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 271*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 272*1c2bbba8SAndroid Build Coastguard Worker } 273*1c2bbba8SAndroid Build Coastguard Worker 274*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 275*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 276*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String value); 277*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setNumberOfLegs(int value); 278*1c2bbba8SAndroid Build Coastguard Worker 279*1c2bbba8SAndroid Build Coastguard Worker abstract Optional<String> name(); 280*1c2bbba8SAndroid Build Coastguard Worker abstract int numberOfLegs(); 281*1c2bbba8SAndroid Build Coastguard Worker 282*1c2bbba8SAndroid Build Coastguard Worker abstract Animal autoBuild(); // not public 283*1c2bbba8SAndroid Build Coastguard Worker 284*1c2bbba8SAndroid Build Coastguard Worker public final Animal build() { 285*1c2bbba8SAndroid Build Coastguard Worker if (name().isEmpty()) { 286*1c2bbba8SAndroid Build Coastguard Worker setName(numberOfLegs() + "-legged creature"); 287*1c2bbba8SAndroid Build Coastguard Worker } 288*1c2bbba8SAndroid Build Coastguard Worker return autoBuild(); 289*1c2bbba8SAndroid Build Coastguard Worker } 290*1c2bbba8SAndroid Build Coastguard Worker } 291*1c2bbba8SAndroid Build Coastguard Worker} 292*1c2bbba8SAndroid Build Coastguard Worker``` 293*1c2bbba8SAndroid Build Coastguard Worker 294*1c2bbba8SAndroid Build Coastguard WorkerNotice that this will throw `IllegalStateException` if the `numberOfLegs` 295*1c2bbba8SAndroid Build Coastguard Workerproperty hasn't been set either. 296*1c2bbba8SAndroid Build Coastguard Worker 297*1c2bbba8SAndroid Build Coastguard WorkerThe Optional wrapping can be any of the Optional types mentioned in the 298*1c2bbba8SAndroid Build Coastguard Worker[section](#optional) on `Optional` properties. If your property has type `int` 299*1c2bbba8SAndroid Build Coastguard Workerit can be wrapped as either `Optional<Integer>` or `OptionalInt`, and likewise 300*1c2bbba8SAndroid Build Coastguard Workerfor `long` and `double`. 301*1c2bbba8SAndroid Build Coastguard Worker 302*1c2bbba8SAndroid Build Coastguard Worker## <a name="both"></a>... expose *both* a builder *and* a factory method? 303*1c2bbba8SAndroid Build Coastguard Worker 304*1c2bbba8SAndroid Build Coastguard WorkerIf you use the builder option, AutoValue will not generate a visible constructor 305*1c2bbba8SAndroid Build Coastguard Workerfor the generated concrete value class. If it's important to offer your caller 306*1c2bbba8SAndroid Build Coastguard Workerthe choice of a factory method as well as the builder, then your factory method 307*1c2bbba8SAndroid Build Coastguard Workerimplementation will have to invoke the builder itself. 308*1c2bbba8SAndroid Build Coastguard Worker 309*1c2bbba8SAndroid Build Coastguard Worker## <a name="optional"></a>... handle `Optional` properties? 310*1c2bbba8SAndroid Build Coastguard Worker 311*1c2bbba8SAndroid Build Coastguard WorkerProperties of type `Optional` benefit from special treatment. If you have a 312*1c2bbba8SAndroid Build Coastguard Workerproperty of type `Optional<String>`, say, then it will default to an empty 313*1c2bbba8SAndroid Build Coastguard Worker`Optional` without needing to [specify](#default) a default explicitly. And, 314*1c2bbba8SAndroid Build Coastguard Workerinstead of or as well as the normal `setFoo(Optional<String>)` method, you can 315*1c2bbba8SAndroid Build Coastguard Workerhave `setFoo(String)`. Then `setFoo(s)` is equivalent to 316*1c2bbba8SAndroid Build Coastguard Worker`setFoo(Optional.of(s))`. (If it is `setFoo(@Nullable String)`, then `setFoo(s)` 317*1c2bbba8SAndroid Build Coastguard Workeris equivalent to `setFoo(Optional.ofNullable(s))`.) 318*1c2bbba8SAndroid Build Coastguard Worker 319*1c2bbba8SAndroid Build Coastguard WorkerHere, `Optional` means either [`java.util.Optional`] from Java (Java 8 or 320*1c2bbba8SAndroid Build Coastguard Workerlater), or [`com.google.common.base.Optional`] from Guava. Java 8 also 321*1c2bbba8SAndroid Build Coastguard Workerintroduced related classes in `java.util` called [`OptionalInt`], 322*1c2bbba8SAndroid Build Coastguard Worker[`OptionalLong`], and [`OptionalDouble`]. You can use those in the same way. For 323*1c2bbba8SAndroid Build Coastguard Workerexample a property of type `OptionalInt` will default to `OptionalInt.empty()` 324*1c2bbba8SAndroid Build Coastguard Workerand you can set it with either `setFoo(OptionalInt)` or `setFoo(int)`. 325*1c2bbba8SAndroid Build Coastguard Worker 326*1c2bbba8SAndroid Build Coastguard Worker```java 327*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 328*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 329*1c2bbba8SAndroid Build Coastguard Worker public abstract Optional<String> name(); 330*1c2bbba8SAndroid Build Coastguard Worker 331*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 332*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 333*1c2bbba8SAndroid Build Coastguard Worker } 334*1c2bbba8SAndroid Build Coastguard Worker 335*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 336*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 337*1c2bbba8SAndroid Build Coastguard Worker // You can have either or both of these two methods: 338*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(Optional<String> value); 339*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String value); 340*1c2bbba8SAndroid Build Coastguard Worker public abstract Animal build(); 341*1c2bbba8SAndroid Build Coastguard Worker } 342*1c2bbba8SAndroid Build Coastguard Worker} 343*1c2bbba8SAndroid Build Coastguard Worker``` 344*1c2bbba8SAndroid Build Coastguard Worker 345*1c2bbba8SAndroid Build Coastguard Worker[`java.util.Optional`]: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html 346*1c2bbba8SAndroid Build Coastguard Worker[`com.google.common.base.Optional`]: https://guava.dev/releases/snapshot/api/docs/com/google/common/base/Optional.html 347*1c2bbba8SAndroid Build Coastguard Worker[`OptionalDouble`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalDouble.html 348*1c2bbba8SAndroid Build Coastguard Worker[`OptionalInt`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalInt.html 349*1c2bbba8SAndroid Build Coastguard Worker[`OptionalLong`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalLong.html 350*1c2bbba8SAndroid Build Coastguard Worker 351*1c2bbba8SAndroid Build Coastguard Worker## <a name="collection"></a>... use a collection-valued property? 352*1c2bbba8SAndroid Build Coastguard Worker 353*1c2bbba8SAndroid Build Coastguard WorkerValue objects should be immutable, so if a property of one is a collection then 354*1c2bbba8SAndroid Build Coastguard Workerthat collection should be immutable too. We recommend using Guava's [immutable 355*1c2bbba8SAndroid Build Coastguard Workercollections] to make that explicit. AutoValue's builder support includes a few 356*1c2bbba8SAndroid Build Coastguard Workerspecial arrangements to make this more convenient. 357*1c2bbba8SAndroid Build Coastguard Worker 358*1c2bbba8SAndroid Build Coastguard WorkerIn the examples here we use `ImmutableSet`, but the same principles apply to all 359*1c2bbba8SAndroid Build Coastguard Workerof Guava's immutable collection types, like `ImmutableList`, 360*1c2bbba8SAndroid Build Coastguard Worker`ImmutableMultimap`, and so on. 361*1c2bbba8SAndroid Build Coastguard Worker 362*1c2bbba8SAndroid Build Coastguard WorkerWe recommend using the immutable type (like `ImmutableSet<String>`) as your 363*1c2bbba8SAndroid Build Coastguard Workeractual property type. However, it can be a pain for callers to always have to 364*1c2bbba8SAndroid Build Coastguard Workerconstruct `ImmutableSet` instances to pass into your builder. So AutoValue 365*1c2bbba8SAndroid Build Coastguard Workerallows your builder method to accept an argument of any type that 366*1c2bbba8SAndroid Build Coastguard Worker`ImmutableSet.copyOf` accepts. 367*1c2bbba8SAndroid Build Coastguard Worker 368*1c2bbba8SAndroid Build Coastguard WorkerIf our `Animal` acquires an `ImmutableSet<String>` that is the countries it 369*1c2bbba8SAndroid Build Coastguard Workerlives in, that can be set from a `Set<String>` or a `Collection<String>` or an 370*1c2bbba8SAndroid Build Coastguard Worker`Iterable<String>` or a `String[]` or any other compatible type. You can even 371*1c2bbba8SAndroid Build Coastguard Workeroffer multiple choices, as in this example: 372*1c2bbba8SAndroid Build Coastguard Worker 373*1c2bbba8SAndroid Build Coastguard Worker```java 374*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 375*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 376*1c2bbba8SAndroid Build Coastguard Worker public abstract String name(); 377*1c2bbba8SAndroid Build Coastguard Worker public abstract int numberOfLegs(); 378*1c2bbba8SAndroid Build Coastguard Worker public abstract ImmutableSet<String> countries(); 379*1c2bbba8SAndroid Build Coastguard Worker 380*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 381*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 382*1c2bbba8SAndroid Build Coastguard Worker } 383*1c2bbba8SAndroid Build Coastguard Worker 384*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 385*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 386*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String value); 387*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setNumberOfLegs(int value); 388*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setCountries(Set<String> value); 389*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setCountries(String... value); 390*1c2bbba8SAndroid Build Coastguard Worker public abstract Animal build(); 391*1c2bbba8SAndroid Build Coastguard Worker } 392*1c2bbba8SAndroid Build Coastguard Worker} 393*1c2bbba8SAndroid Build Coastguard Worker``` 394*1c2bbba8SAndroid Build Coastguard Worker 395*1c2bbba8SAndroid Build Coastguard Worker[immutable collections]: https://github.com/google/guava/wiki/ImmutableCollectionsExplained 396*1c2bbba8SAndroid Build Coastguard Worker 397*1c2bbba8SAndroid Build Coastguard Worker### <a name="accumulate"></a>... let my builder *accumulate* values for a collection-valued property (not require them all at once)? 398*1c2bbba8SAndroid Build Coastguard Worker 399*1c2bbba8SAndroid Build Coastguard WorkerInstead of defining a setter for an immutable collection `foos`, you can define 400*1c2bbba8SAndroid Build Coastguard Workera method `foosBuilder()` that returns the associated builder type for that 401*1c2bbba8SAndroid Build Coastguard Workercollection. In this example, we have an `ImmutableSet<String>` which can be 402*1c2bbba8SAndroid Build Coastguard Workerbuilt using the `countriesBuilder()` method: 403*1c2bbba8SAndroid Build Coastguard Worker 404*1c2bbba8SAndroid Build Coastguard Worker```java 405*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 406*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 407*1c2bbba8SAndroid Build Coastguard Worker public abstract String name(); 408*1c2bbba8SAndroid Build Coastguard Worker public abstract int numberOfLegs(); 409*1c2bbba8SAndroid Build Coastguard Worker public abstract ImmutableSet<String> countries(); 410*1c2bbba8SAndroid Build Coastguard Worker 411*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 412*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 413*1c2bbba8SAndroid Build Coastguard Worker } 414*1c2bbba8SAndroid Build Coastguard Worker 415*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 416*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 417*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String value); 418*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setNumberOfLegs(int value); 419*1c2bbba8SAndroid Build Coastguard Worker public abstract ImmutableSet.Builder<String> countriesBuilder(); 420*1c2bbba8SAndroid Build Coastguard Worker public abstract Animal build(); 421*1c2bbba8SAndroid Build Coastguard Worker } 422*1c2bbba8SAndroid Build Coastguard Worker} 423*1c2bbba8SAndroid Build Coastguard Worker``` 424*1c2bbba8SAndroid Build Coastguard Worker 425*1c2bbba8SAndroid Build Coastguard WorkerThe name of this method must be exactly the property name (`countries` here) 426*1c2bbba8SAndroid Build Coastguard Workerfollowed by the string `Builder`. Even if the properties follow the 427*1c2bbba8SAndroid Build Coastguard Worker`getCountries()` convention, the builder method must be `countriesBuilder()` 428*1c2bbba8SAndroid Build Coastguard Workerand not `getCountriesBuilder()`. 429*1c2bbba8SAndroid Build Coastguard Worker 430*1c2bbba8SAndroid Build Coastguard WorkerIt's also possible to have a method like `countriesBuilder` with a single 431*1c2bbba8SAndroid Build Coastguard Workerargument, provided that the `Builder` class has a public constructor or a 432*1c2bbba8SAndroid Build Coastguard Workerstatic `builder` method, with one parameter that the argument can be assigned 433*1c2bbba8SAndroid Build Coastguard Workerto. For example, if `countries()` were an `ImmutableSortedSet<String>` and you 434*1c2bbba8SAndroid Build Coastguard Workerwanted to supply a `Comparator` to `ImmutableSortedSet.Builder`, you could 435*1c2bbba8SAndroid Build Coastguard Workerwrite: 436*1c2bbba8SAndroid Build Coastguard Worker 437*1c2bbba8SAndroid Build Coastguard Worker```java 438*1c2bbba8SAndroid Build Coastguard Worker public abstract ImmutableSortedSet.Builder<String> 439*1c2bbba8SAndroid Build Coastguard Worker countriesBuilder(Comparator<String> comparator); 440*1c2bbba8SAndroid Build Coastguard Worker``` 441*1c2bbba8SAndroid Build Coastguard Worker 442*1c2bbba8SAndroid Build Coastguard WorkerThat works because `ImmutableSortedSet.Builder` has a constructor that 443*1c2bbba8SAndroid Build Coastguard Workeraccepts a `Comparator` parameter. 444*1c2bbba8SAndroid Build Coastguard Worker 445*1c2bbba8SAndroid Build Coastguard WorkerYou may notice a small problem with these examples: the caller can no longer 446*1c2bbba8SAndroid Build Coastguard Workercreate their instance in a single chained statement: 447*1c2bbba8SAndroid Build Coastguard Worker 448*1c2bbba8SAndroid Build Coastguard Worker```java 449*1c2bbba8SAndroid Build Coastguard Worker // This DOES NOT work! 450*1c2bbba8SAndroid Build Coastguard Worker Animal dog = Animal.builder() 451*1c2bbba8SAndroid Build Coastguard Worker .setName("dog") 452*1c2bbba8SAndroid Build Coastguard Worker .setNumberOfLegs(4) 453*1c2bbba8SAndroid Build Coastguard Worker .countriesBuilder() 454*1c2bbba8SAndroid Build Coastguard Worker .add("Guam") 455*1c2bbba8SAndroid Build Coastguard Worker .add("Laos") 456*1c2bbba8SAndroid Build Coastguard Worker .build(); 457*1c2bbba8SAndroid Build Coastguard Worker``` 458*1c2bbba8SAndroid Build Coastguard Worker 459*1c2bbba8SAndroid Build Coastguard WorkerInstead they are forced to hold the builder itself in a temporary variable: 460*1c2bbba8SAndroid Build Coastguard Worker 461*1c2bbba8SAndroid Build Coastguard Worker```java 462*1c2bbba8SAndroid Build Coastguard Worker // This DOES work... but we have to "break the chain"! 463*1c2bbba8SAndroid Build Coastguard Worker Animal.Builder builder = Animal.builder() 464*1c2bbba8SAndroid Build Coastguard Worker .setName("dog") 465*1c2bbba8SAndroid Build Coastguard Worker .setNumberOfLegs(4); 466*1c2bbba8SAndroid Build Coastguard Worker builder.countriesBuilder() 467*1c2bbba8SAndroid Build Coastguard Worker .add("Guam") 468*1c2bbba8SAndroid Build Coastguard Worker .add("Laos"); 469*1c2bbba8SAndroid Build Coastguard Worker Animal dog = builder.build(); 470*1c2bbba8SAndroid Build Coastguard Worker``` 471*1c2bbba8SAndroid Build Coastguard Worker 472*1c2bbba8SAndroid Build Coastguard WorkerOne solution for this problem is just below. 473*1c2bbba8SAndroid Build Coastguard Worker 474*1c2bbba8SAndroid Build Coastguard Worker### <a name="add"></a>... accumulate values for a collection-valued property, without "breaking the chain"? 475*1c2bbba8SAndroid Build Coastguard Worker 476*1c2bbba8SAndroid Build Coastguard WorkerAnother option is to keep `countriesBuilder()` itself non-public, and only use 477*1c2bbba8SAndroid Build Coastguard Workerit to implement a public `addCountry` method: 478*1c2bbba8SAndroid Build Coastguard Worker 479*1c2bbba8SAndroid Build Coastguard Worker```java 480*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 481*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 482*1c2bbba8SAndroid Build Coastguard Worker public abstract String name(); 483*1c2bbba8SAndroid Build Coastguard Worker public abstract int numberOfLegs(); 484*1c2bbba8SAndroid Build Coastguard Worker public abstract ImmutableSet<String> countries(); 485*1c2bbba8SAndroid Build Coastguard Worker 486*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 487*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 488*1c2bbba8SAndroid Build Coastguard Worker } 489*1c2bbba8SAndroid Build Coastguard Worker 490*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 491*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 492*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String value); 493*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setNumberOfLegs(int value); 494*1c2bbba8SAndroid Build Coastguard Worker 495*1c2bbba8SAndroid Build Coastguard Worker abstract ImmutableSet.Builder<String> countriesBuilder(); 496*1c2bbba8SAndroid Build Coastguard Worker public final Builder addCountry(String value) { 497*1c2bbba8SAndroid Build Coastguard Worker countriesBuilder().add(value); 498*1c2bbba8SAndroid Build Coastguard Worker return this; 499*1c2bbba8SAndroid Build Coastguard Worker } 500*1c2bbba8SAndroid Build Coastguard Worker 501*1c2bbba8SAndroid Build Coastguard Worker public abstract Animal build(); 502*1c2bbba8SAndroid Build Coastguard Worker } 503*1c2bbba8SAndroid Build Coastguard Worker} 504*1c2bbba8SAndroid Build Coastguard Worker``` 505*1c2bbba8SAndroid Build Coastguard Worker 506*1c2bbba8SAndroid Build Coastguard WorkerNow the caller can do this: 507*1c2bbba8SAndroid Build Coastguard Worker 508*1c2bbba8SAndroid Build Coastguard Worker```java 509*1c2bbba8SAndroid Build Coastguard Worker // This DOES work! 510*1c2bbba8SAndroid Build Coastguard Worker Animal dog = Animal.builder() 511*1c2bbba8SAndroid Build Coastguard Worker .setName("dog") 512*1c2bbba8SAndroid Build Coastguard Worker .setNumberOfLegs(4) 513*1c2bbba8SAndroid Build Coastguard Worker .addCountry("Guam") 514*1c2bbba8SAndroid Build Coastguard Worker .addCountry("Laos") // however many times needed 515*1c2bbba8SAndroid Build Coastguard Worker .build(); 516*1c2bbba8SAndroid Build Coastguard Worker``` 517*1c2bbba8SAndroid Build Coastguard Worker 518*1c2bbba8SAndroid Build Coastguard Worker### <a name="collection_both"></a>... offer both accumulation and set-at-once methods for the same collection-valued property? 519*1c2bbba8SAndroid Build Coastguard Worker 520*1c2bbba8SAndroid Build Coastguard WorkerYes, you can provide both methods, letting your caller choose the style they 521*1c2bbba8SAndroid Build Coastguard Workerprefer. 522*1c2bbba8SAndroid Build Coastguard Worker 523*1c2bbba8SAndroid Build Coastguard WorkerThe same caller can mix the two styles only in limited ways; once `foosBuilder` 524*1c2bbba8SAndroid Build Coastguard Workerhas been called, any subsequent call to `setFoos` will throw an unchecked 525*1c2bbba8SAndroid Build Coastguard Workerexception. On the other hand, calling `setFoos` first is okay; a later call to 526*1c2bbba8SAndroid Build Coastguard Worker`foosBuilder` will return a builder already populated with the 527*1c2bbba8SAndroid Build Coastguard Workerpreviously-supplied elements. 528*1c2bbba8SAndroid Build Coastguard Worker 529*1c2bbba8SAndroid Build Coastguard Worker## <a name="nested_builders"></a>... access nested builders while building? 530*1c2bbba8SAndroid Build Coastguard Worker 531*1c2bbba8SAndroid Build Coastguard WorkerOften a property of an `@AutoValue` class is itself an immutable class, 532*1c2bbba8SAndroid Build Coastguard Workerperhaps another `@AutoValue`. In such cases your builder can expose a builder 533*1c2bbba8SAndroid Build Coastguard Workerfor that nested class. This is very similar to exposing a builder for a 534*1c2bbba8SAndroid Build Coastguard Workercollection property, as described [earlier](#accumulate). 535*1c2bbba8SAndroid Build Coastguard Worker 536*1c2bbba8SAndroid Build Coastguard WorkerSuppose the `Animal` class has a property of type `Species`: 537*1c2bbba8SAndroid Build Coastguard Worker 538*1c2bbba8SAndroid Build Coastguard Worker```java 539*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 540*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Animal { 541*1c2bbba8SAndroid Build Coastguard Worker public abstract String name(); 542*1c2bbba8SAndroid Build Coastguard Worker public abstract Species species(); 543*1c2bbba8SAndroid Build Coastguard Worker 544*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 545*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Animal.Builder(); 546*1c2bbba8SAndroid Build Coastguard Worker } 547*1c2bbba8SAndroid Build Coastguard Worker 548*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 549*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 550*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setName(String name); 551*1c2bbba8SAndroid Build Coastguard Worker public abstract Species.Builder speciesBuilder(); 552*1c2bbba8SAndroid Build Coastguard Worker public abstract Animal build(); 553*1c2bbba8SAndroid Build Coastguard Worker } 554*1c2bbba8SAndroid Build Coastguard Worker} 555*1c2bbba8SAndroid Build Coastguard Worker 556*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 557*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Species { 558*1c2bbba8SAndroid Build Coastguard Worker public abstract String genus(); 559*1c2bbba8SAndroid Build Coastguard Worker public abstract String epithet(); 560*1c2bbba8SAndroid Build Coastguard Worker 561*1c2bbba8SAndroid Build Coastguard Worker public static Builder builder() { 562*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Species.Builder(); 563*1c2bbba8SAndroid Build Coastguard Worker } 564*1c2bbba8SAndroid Build Coastguard Worker 565*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 566*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 567*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setGenus(String genus); 568*1c2bbba8SAndroid Build Coastguard Worker public abstract Builder setEpithet(String epithet); 569*1c2bbba8SAndroid Build Coastguard Worker public abstract Species build(); 570*1c2bbba8SAndroid Build Coastguard Worker } 571*1c2bbba8SAndroid Build Coastguard Worker} 572*1c2bbba8SAndroid Build Coastguard Worker``` 573*1c2bbba8SAndroid Build Coastguard Worker 574*1c2bbba8SAndroid Build Coastguard WorkerNow you can access the builder of the nested `Species` while you are building 575*1c2bbba8SAndroid Build Coastguard Workerthe `Animal`: 576*1c2bbba8SAndroid Build Coastguard Worker 577*1c2bbba8SAndroid Build Coastguard Worker```java 578*1c2bbba8SAndroid Build Coastguard Worker Animal.Builder catBuilder = Animal.builder() 579*1c2bbba8SAndroid Build Coastguard Worker .setName("cat"); 580*1c2bbba8SAndroid Build Coastguard Worker catBuilder.speciesBuilder() 581*1c2bbba8SAndroid Build Coastguard Worker .setGenus("Felis") 582*1c2bbba8SAndroid Build Coastguard Worker .setEpithet("catus"); 583*1c2bbba8SAndroid Build Coastguard Worker Animal cat = catBuilder.build(); 584*1c2bbba8SAndroid Build Coastguard Worker``` 585*1c2bbba8SAndroid Build Coastguard Worker 586*1c2bbba8SAndroid Build Coastguard WorkerAlthough the nested class in the example (`Species`) is also an `@AutoValue` 587*1c2bbba8SAndroid Build Coastguard Workerclass, it does not have to be. For example, it could be a [protobuf]. The 588*1c2bbba8SAndroid Build Coastguard Workerrequirements are: 589*1c2bbba8SAndroid Build Coastguard Worker 590*1c2bbba8SAndroid Build Coastguard Worker* The nested class must have a way to make a new builder. This can be 591*1c2bbba8SAndroid Build Coastguard Worker `new Species.Builder()`, or `Species.builder()`, or `Species.newBuilder()`. 592*1c2bbba8SAndroid Build Coastguard Worker 593*1c2bbba8SAndroid Build Coastguard Worker* There must be a way to build an instance from the builder: `Species.Builder` 594*1c2bbba8SAndroid Build Coastguard Worker must have a method `Species build()`. 595*1c2bbba8SAndroid Build Coastguard Worker 596*1c2bbba8SAndroid Build Coastguard Worker* If there is a need to convert `Species` back into its builder, then `Species` 597*1c2bbba8SAndroid Build Coastguard Worker must have a method `Species.Builder toBuilder()`. 598*1c2bbba8SAndroid Build Coastguard Worker 599*1c2bbba8SAndroid Build Coastguard Worker In the example, if `Animal` has an abstract [`toBuilder()`](#to_builder) 600*1c2bbba8SAndroid Build Coastguard Worker method then `Species` must also have a `toBuilder()` method. That also applies 601*1c2bbba8SAndroid Build Coastguard Worker if there is an abstract `setSpecies` method in addition to the 602*1c2bbba8SAndroid Build Coastguard Worker `speciesBuilder` method. 603*1c2bbba8SAndroid Build Coastguard Worker 604*1c2bbba8SAndroid Build Coastguard Worker As an alternative to having a method `Species.Builder toBuilder()` in 605*1c2bbba8SAndroid Build Coastguard Worker `Species`, `Species.Builder` can have a method called `addAll` or `putAll` 606*1c2bbba8SAndroid Build Coastguard Worker that accepts an argument of type `Species`. This is how AutoValue handles 607*1c2bbba8SAndroid Build Coastguard Worker `ImmutableSet` for example. `ImmutableSet` does not have a `toBuilder()` 608*1c2bbba8SAndroid Build Coastguard Worker method, but `ImmutableSet.Builder` does have an `addAll` method that accepts 609*1c2bbba8SAndroid Build Coastguard Worker an `ImmutableSet`. So given `ImmutableSet<String> strings`, we can achieve the 610*1c2bbba8SAndroid Build Coastguard Worker effect of `strings.toBuilder()` by doing: 611*1c2bbba8SAndroid Build Coastguard Worker 612*1c2bbba8SAndroid Build Coastguard Worker ``` 613*1c2bbba8SAndroid Build Coastguard Worker ImmutableSet.Builder<String> builder = ImmutableSet.builder(); 614*1c2bbba8SAndroid Build Coastguard Worker builder.addAll(strings); 615*1c2bbba8SAndroid Build Coastguard Worker ``` 616*1c2bbba8SAndroid Build Coastguard Worker 617*1c2bbba8SAndroid Build Coastguard WorkerThere are no requirements on the name of the builder class. Instead of 618*1c2bbba8SAndroid Build Coastguard Worker`Species.Builder`, it could be `Species.Factory` or `SpeciesBuilder`. 619*1c2bbba8SAndroid Build Coastguard Worker 620*1c2bbba8SAndroid Build Coastguard WorkerIf `speciesBuilder()` is never called then the final `species()` property will 621*1c2bbba8SAndroid Build Coastguard Workerbe set as if by `speciesBuilder().build()`. In the example, that would result 622*1c2bbba8SAndroid Build Coastguard Workerin an exception because the required properties of `Species` have not been set. 623*1c2bbba8SAndroid Build Coastguard Worker 624*1c2bbba8SAndroid Build Coastguard Worker## <a name="step"></a>... create a "step builder"? 625*1c2bbba8SAndroid Build Coastguard Worker 626*1c2bbba8SAndroid Build Coastguard WorkerA [_step builder_](http://rdafbn.blogspot.com/2012/07/step-builder-pattern_28.html) 627*1c2bbba8SAndroid Build Coastguard Workeris a collection of builder interfaces that take you step by step through the 628*1c2bbba8SAndroid Build Coastguard Workersetting of each of a list of required properties. This means you can be sure at 629*1c2bbba8SAndroid Build Coastguard Workercompile time that all the properties are set before you build, at the expense of 630*1c2bbba8SAndroid Build Coastguard Workersome extra code and a bit less flexibility. 631*1c2bbba8SAndroid Build Coastguard Worker 632*1c2bbba8SAndroid Build Coastguard WorkerHere is an example: 633*1c2bbba8SAndroid Build Coastguard Worker 634*1c2bbba8SAndroid Build Coastguard Worker```java 635*1c2bbba8SAndroid Build Coastguard Worker@AutoValue 636*1c2bbba8SAndroid Build Coastguard Workerpublic abstract class Stepped { 637*1c2bbba8SAndroid Build Coastguard Worker public abstract String foo(); 638*1c2bbba8SAndroid Build Coastguard Worker public abstract String bar(); 639*1c2bbba8SAndroid Build Coastguard Worker public abstract int baz(); 640*1c2bbba8SAndroid Build Coastguard Worker 641*1c2bbba8SAndroid Build Coastguard Worker public static FooStep builder() { 642*1c2bbba8SAndroid Build Coastguard Worker return new AutoValue_Stepped.Builder(); 643*1c2bbba8SAndroid Build Coastguard Worker } 644*1c2bbba8SAndroid Build Coastguard Worker 645*1c2bbba8SAndroid Build Coastguard Worker public interface FooStep { 646*1c2bbba8SAndroid Build Coastguard Worker BarStep setFoo(String foo); 647*1c2bbba8SAndroid Build Coastguard Worker } 648*1c2bbba8SAndroid Build Coastguard Worker 649*1c2bbba8SAndroid Build Coastguard Worker public interface BarStep { 650*1c2bbba8SAndroid Build Coastguard Worker BazStep setBar(String bar); 651*1c2bbba8SAndroid Build Coastguard Worker } 652*1c2bbba8SAndroid Build Coastguard Worker 653*1c2bbba8SAndroid Build Coastguard Worker public interface BazStep { 654*1c2bbba8SAndroid Build Coastguard Worker Build setBaz(int baz); 655*1c2bbba8SAndroid Build Coastguard Worker } 656*1c2bbba8SAndroid Build Coastguard Worker 657*1c2bbba8SAndroid Build Coastguard Worker public interface Build { 658*1c2bbba8SAndroid Build Coastguard Worker Stepped build(); 659*1c2bbba8SAndroid Build Coastguard Worker } 660*1c2bbba8SAndroid Build Coastguard Worker 661*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 662*1c2bbba8SAndroid Build Coastguard Worker abstract static class Builder implements FooStep, BarStep, BazStep, Build {} 663*1c2bbba8SAndroid Build Coastguard Worker} 664*1c2bbba8SAndroid Build Coastguard Worker``` 665*1c2bbba8SAndroid Build Coastguard Worker 666*1c2bbba8SAndroid Build Coastguard WorkerIt might be used like this: 667*1c2bbba8SAndroid Build Coastguard Worker 668*1c2bbba8SAndroid Build Coastguard Worker```java 669*1c2bbba8SAndroid Build Coastguard WorkerStepped stepped = Stepped.builder().setFoo("foo").setBar("bar").setBaz(3).build(); 670*1c2bbba8SAndroid Build Coastguard Worker``` 671*1c2bbba8SAndroid Build Coastguard Worker 672*1c2bbba8SAndroid Build Coastguard WorkerThe idea is that the only way to build an instance of `Stepped` 673*1c2bbba8SAndroid Build Coastguard Workeris to go through the steps imposed by the `FooStep`, `BarStep`, and 674*1c2bbba8SAndroid Build Coastguard Worker`BazStep` interfaces to set the properties in order, with a final build step. 675*1c2bbba8SAndroid Build Coastguard Worker 676*1c2bbba8SAndroid Build Coastguard WorkerOnce you have set the `baz` property there is nothing else to do except build, 677*1c2bbba8SAndroid Build Coastguard Workerso you could also combine the `setBaz` and `build` methods like this: 678*1c2bbba8SAndroid Build Coastguard Worker 679*1c2bbba8SAndroid Build Coastguard Worker```java 680*1c2bbba8SAndroid Build Coastguard Worker ... 681*1c2bbba8SAndroid Build Coastguard Worker 682*1c2bbba8SAndroid Build Coastguard Worker public interface BazStep { 683*1c2bbba8SAndroid Build Coastguard Worker Stepped setBazAndBuild(int baz); 684*1c2bbba8SAndroid Build Coastguard Worker } 685*1c2bbba8SAndroid Build Coastguard Worker 686*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 687*1c2bbba8SAndroid Build Coastguard Worker abstract static class Builder implements FooStep, BarStep, BazStep { 688*1c2bbba8SAndroid Build Coastguard Worker abstract Builder setBaz(int baz); 689*1c2bbba8SAndroid Build Coastguard Worker abstract Stepped build(); 690*1c2bbba8SAndroid Build Coastguard Worker 691*1c2bbba8SAndroid Build Coastguard Worker @Override 692*1c2bbba8SAndroid Build Coastguard Worker public Stepped setBazAndBuild(int baz) { 693*1c2bbba8SAndroid Build Coastguard Worker return setBaz(baz).build(); 694*1c2bbba8SAndroid Build Coastguard Worker } 695*1c2bbba8SAndroid Build Coastguard Worker } 696*1c2bbba8SAndroid Build Coastguard Worker``` 697*1c2bbba8SAndroid Build Coastguard Worker 698*1c2bbba8SAndroid Build Coastguard Worker## <a name="autobuilder"></a> ... create a builder for something other than an `@AutoValue`? 699*1c2bbba8SAndroid Build Coastguard Worker 700*1c2bbba8SAndroid Build Coastguard WorkerSometimes you want to make a builder like the kind described here, but have it 701*1c2bbba8SAndroid Build Coastguard Workerbuild something other than an `@AutoValue` class, or even call a static method. 702*1c2bbba8SAndroid Build Coastguard WorkerIn that case you can use `@AutoBuilder`. See 703*1c2bbba8SAndroid Build Coastguard Worker[its documentation](autobuilder.md). 704*1c2bbba8SAndroid Build Coastguard Worker 705*1c2bbba8SAndroid Build Coastguard WorkerSometimes you want to use a different build method for your property. This is 706*1c2bbba8SAndroid Build Coastguard Workerespecially applicable for `ImmutableMap`, which has two different build methods. 707*1c2bbba8SAndroid Build Coastguard Worker`builder.buildOrThrow()` is used as the default build method for AutoValue. You 708*1c2bbba8SAndroid Build Coastguard Workermight prefer to use `builder.buildKeepingLast()` instead, so if the same key is 709*1c2bbba8SAndroid Build Coastguard Workerput more than once then the last value is retained rather than throwing an 710*1c2bbba8SAndroid Build Coastguard Workerexception. AutoValue doesn't currently have a way to request this, but here is a 711*1c2bbba8SAndroid Build Coastguard Workerworkaround if you need it. Let's say you have a class like this: 712*1c2bbba8SAndroid Build Coastguard Worker 713*1c2bbba8SAndroid Build Coastguard Worker```java 714*1c2bbba8SAndroid Build Coastguard Worker @AutoValue 715*1c2bbba8SAndroid Build Coastguard Worker public abstract class Foo { 716*1c2bbba8SAndroid Build Coastguard Worker public abstract ImmutableMap<Integer, String> map(); 717*1c2bbba8SAndroid Build Coastguard Worker ... 718*1c2bbba8SAndroid Build Coastguard Worker 719*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 720*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 721*1c2bbba8SAndroid Build Coastguard Worker public abstract ImmutableMap.Builder<Integer, String> mapBuilder(); 722*1c2bbba8SAndroid Build Coastguard Worker public abstract Foo build(); 723*1c2bbba8SAndroid Build Coastguard Worker } 724*1c2bbba8SAndroid Build Coastguard Worker } 725*1c2bbba8SAndroid Build Coastguard Worker``` 726*1c2bbba8SAndroid Build Coastguard Worker 727*1c2bbba8SAndroid Build Coastguard WorkerInstead, you could write this: 728*1c2bbba8SAndroid Build Coastguard Worker 729*1c2bbba8SAndroid Build Coastguard Worker```java 730*1c2bbba8SAndroid Build Coastguard Worker @AutoValue 731*1c2bbba8SAndroid Build Coastguard Worker public abstract class Foo { 732*1c2bbba8SAndroid Build Coastguard Worker public abstract ImmutableMap<Integer, String> map(); 733*1c2bbba8SAndroid Build Coastguard Worker 734*1c2bbba8SAndroid Build Coastguard Worker // #start 735*1c2bbba8SAndroid Build Coastguard Worker // Needed only if your class has toBuilder() method 736*1c2bbba8SAndroid Build Coastguard Worker public Builder toBuilder() { 737*1c2bbba8SAndroid Build Coastguard Worker Builder builder = autoToBuilder(); 738*1c2bbba8SAndroid Build Coastguard Worker builder.mapBuilder().putAll(map()); 739*1c2bbba8SAndroid Build Coastguard Worker return builder; 740*1c2bbba8SAndroid Build Coastguard Worker } 741*1c2bbba8SAndroid Build Coastguard Worker 742*1c2bbba8SAndroid Build Coastguard Worker abstract Builder autoToBuilder(); // not public 743*1c2bbba8SAndroid Build Coastguard Worker // #end 744*1c2bbba8SAndroid Build Coastguard Worker 745*1c2bbba8SAndroid Build Coastguard Worker @AutoValue.Builder 746*1c2bbba8SAndroid Build Coastguard Worker public abstract static class Builder { 747*1c2bbba8SAndroid Build Coastguard Worker 748*1c2bbba8SAndroid Build Coastguard Worker private final ImmutableMap.Builder<Integer, String> mapBuilder = ImmutableMap.builder(); 749*1c2bbba8SAndroid Build Coastguard Worker 750*1c2bbba8SAndroid Build Coastguard Worker public ImmutableMap.Builder<Integer, String> mapBuilder() { 751*1c2bbba8SAndroid Build Coastguard Worker return mapBuilder; 752*1c2bbba8SAndroid Build Coastguard Worker } 753*1c2bbba8SAndroid Build Coastguard Worker 754*1c2bbba8SAndroid Build Coastguard Worker abstract Builder setMap(ImmutableMap<Integer, String> map); // not public 755*1c2bbba8SAndroid Build Coastguard Worker 756*1c2bbba8SAndroid Build Coastguard Worker abstract Foo autoBuild(); // not public 757*1c2bbba8SAndroid Build Coastguard Worker 758*1c2bbba8SAndroid Build Coastguard Worker public Foo build() { 759*1c2bbba8SAndroid Build Coastguard Worker setMap(mapBuilder.buildKeepingLast()); 760*1c2bbba8SAndroid Build Coastguard Worker return autoBuild(); 761*1c2bbba8SAndroid Build Coastguard Worker } 762*1c2bbba8SAndroid Build Coastguard Worker } 763*1c2bbba8SAndroid Build Coastguard Worker } 764*1c2bbba8SAndroid Build Coastguard Worker``` 765*1c2bbba8SAndroid Build Coastguard Worker 766*1c2bbba8SAndroid Build Coastguard Worker[protobuf]: https://developers.google.com/protocol-buffers/docs/reference/java-generated#builders 767