# AutoValue with Builders The [introduction](index.md) of this User Guide covers the basic usage of AutoValue using a static factory method as your public creation API. But in many circumstances (such as those laid out in *Effective Java, 2nd Edition* Item 2), you may prefer to let your callers use a *builder* instead. Fortunately, AutoValue can generate builder classes too! This page explains how. Note that we recommend reading and understanding the basic usage shown in the [introduction](index.md) first. ## How to use AutoValue with Builders As explained in the introduction, the AutoValue concept is that **you write an abstract value class, and AutoValue implements it**. Builder generation works in the exact same way: you also create an abstract builder class, nesting it inside your abstract value class, and AutoValue generates implementations for both. ### In `Animal.java` ```java import com.google.auto.value.AutoValue; @AutoValue abstract class Animal { abstract String name(); abstract int numberOfLegs(); static Builder builder() { return new AutoValue_Animal.Builder(); } @AutoValue.Builder abstract static class Builder { abstract Builder setName(String value); abstract Builder setNumberOfLegs(int value); abstract Animal build(); } } ``` Note that in real life, some classes and methods would presumably be public and have **Javadoc**. We're leaving these off in the User Guide only to keep the examples clean and short. ### Usage ```java public void testAnimal() { Animal dog = Animal.builder().setName("dog").setNumberOfLegs(4).build(); assertEquals("dog", dog.name()); assertEquals(4, dog.numberOfLegs()); // You probably don't need to write assertions like these; just illustrating. assertTrue( Animal.builder().setName("dog").setNumberOfLegs(4).build().equals(dog)); assertFalse( Animal.builder().setName("cat").setNumberOfLegs(4).build().equals(dog)); assertFalse( Animal.builder().setName("dog").setNumberOfLegs(2).build().equals(dog)); assertEquals("Animal{name=dog, numberOfLegs=4}", dog.toString()); } ``` ### What does AutoValue generate? For the `Animal` example shown above, here is [typical code AutoValue might generate](generated-builder-example.md). ## Warnings Be sure to put the static `builder()` method directly in your value class (e.g., `Animal`) and not the nested abstract `Builder` class. That ensures that the `Animal` class is always initialized before `Builder`. Otherwise you may be exposing yourself to initialization-order problems. ## How do I... * ... [use (or not use) `set` **prefixes**?](builders-howto.md#beans) * ... [use different **names** besides `builder()`/`Builder`/`build()`?](builders-howto.md#build_names) * ... [specify a **default** value for a property?](builders-howto.md#default) * ... [initialize a builder to the same property values as an **existing** value instance](builders-howto.md#to_builder) * ... [include `with-` methods on my value class for creating slightly **altered** instances?](builders-howto.md#withers) * ... [**validate** property values?](builders-howto.md#validate) * ... [**normalize** (modify) a property value at `build` time?](builders-howto.md#normalize) * ... [expose **both** a builder and a factory method?](builders-howto.md#both) * ... [handle `Optional` properties?](builders-howto.md#optional) * ... [use a **collection**-valued property?](builders-howto.md#collection) * ... [let my builder **accumulate** values for a collection-valued property (not require them all at once)?](builders-howto.md#accumulate) * ... [accumulate values for a collection-valued property, without **"breaking the chain"**?](builders-howto.md#add) * ... [offer **both** accumulation and set-at-once methods for the same collection-valued property?](builders-howto.md#collection_both) * ... [access nested builders while building?](builders-howto.md#nested_builders) * ... [create a "step builder"?](builders-howto.md#step) * ... [create a builder for something other than an `@AutoValue`?](builders-howto.md#autobuilder)