### Use Get Prefixes, No Set Prefixes in Builder Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Demonstrates using 'get' prefixes for accessors while omitting 'set' prefixes for builder methods. This configuration is valid and can be used for flexibility in naming conventions. ```java import com.google.auto.value.AutoValue; @AutoValue abstract class Animal { abstract String getName(); abstract int getNumberOfLegs(); static Builder builder() { return new AutoValue_Animal.Builder(); } @AutoValue.Builder abstract static class Builder { abstract Builder name(String value); abstract Builder numberOfLegs(int value); abstract Animal build(); } } ``` -------------------------------- ### AutoValue Usage Example Source: https://github.com/google/auto/blob/main/value/userguide/index.md Demonstrates basic usage of an AutoValue generated class, including creation and assertion of properties. This illustrates AutoValue's API-invisible nature. ```java public void testAnimal() { Animal dog = Animal.create("dog", 4); assertEquals("dog", dog.name()); assertEquals(4, dog.numberOfLegs()); // You probably don't need to write assertions like these; just illustrating. assertTrue(Animal.create("dog", 4).equals(dog)); assertFalse(Animal.create("cat", 4).equals(dog)); assertFalse(Animal.create("dog", 2).equals(dog)); assertEquals("Animal{name=dog, numberOfLegs=4}", dog.toString()); } ``` -------------------------------- ### AutoValue Point class with primitive properties Source: https://github.com/google/auto/blob/main/value/userguide/records.md An example of an AutoValue class with primitive properties 'x' and 'y'. ```java import com.google.auto.value.AutoValue; @AutoValue public abstract class Point { public abstract int x(); public abstract int y(); public static Point of(int x, int y) { return new AutoValue_Point(x, y); } } ``` -------------------------------- ### Custom equals and hashCode for Java Record Source: https://github.com/google/auto/blob/main/value/userguide/records.md Example of overriding equals and hashCode methods in a Java record. Demonstrates direct field access for comparison and hashing. ```java public record Person(String name, int id) { ... @Override public boolean equals(Object o) { return o instanceof Person that && Ascii.equalsIgnoreCase(this.name, that.name) && this.id == that.id; } @Override public int hashCode() { return Objects.hash(Ascii.toLowerCase(name), id); } } ``` -------------------------------- ### Builder with Getter Methods and Default Logic Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md This example shows a builder with getter methods. The build() method includes logic to set a default value for 'nickname' if it's not already present, using the value of 'name'. ```java public class Named { Named(String name, String nickname) {...} @AutoBuilder public abstract static class Builder { public abstract Builder setName(String x); public abstract Builder setNickname(String x); abstract String getName(); abstract Optional getNickname(); abstract Named autoBuild(); public Named build() { if (!getNickname().isPresent()) { setNickname(getName()); } return autoBuild(); } } } ``` -------------------------------- ### Making AutoValue Class Serializable Source: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/g3doc/index.md This example demonstrates how to make an AutoValue class serializable by annotating it with @SerializableAutoValue, activating the extension. ```java import java.io.Serializable; import com.google.auto.value.AutoValue; import com.google.auto.value.extension.serializable.SerializableAutoValue; @SerializableAutoValue // This annotation activates the extension. @AutoValue public abstract class Foo implements Serializable { ... } ``` -------------------------------- ### Custom build method name Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md The build method can be named differently, such as 'call()', to better reflect its action. This example shows calling a static log method. ```java public class LogUtil { public static void log(Level severity, String message, Object... params) {...} @AutoBuilder(callMethod = "log") public interface Caller { Caller setSeverity(Level level); Caller setMessage(String message); Caller setParams(Object... params); void call(); // calls: LogUtil.log(severity, message, params) } } ``` -------------------------------- ### Custom equals and hashCode for AutoValue Class Source: https://github.com/google/auto/blob/main/value/userguide/records.md Example of overriding equals and hashCode methods in an AutoValue class before migrating to records. This sets up the context for record customization. ```java @AutoValue public abstract class Person { ... @Override public boolean equals(Object o) { return o instanceof Person that && Ascii.equalsIgnoreCase(this.name(), that.name()) && this.id() == that.id(); } @Override public int hashCode() { return Objects.hash(Ascii.toLowerCase(name()), id()); } } ``` -------------------------------- ### Normalize Constructor Parameters with Records Source: https://github.com/google/auto/blob/main/value/userguide/records.md Use the record constructor to apply normalization rules, ensuring consistent ordering of parameters for methods like equals. This example normalizes two integers into a min-max order. ```java public record UnorderedPair(int left, int right) { public UnorderedPair { int min = Math.min(left, right); int max = Math.max(left, right); left = min; right = max; } } ``` -------------------------------- ### Java Person Builder Example Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Defines an abstract builder for the Person class. Use this when constructing Person objects from Java code to avoid needing to know the constructor's parameter order. ```java import com.google.auto.value.AutoBuilder; @AutoBuilder(ofClass = Person.class) abstract class PersonBuilder { static PersonBuilder personBuilder() { return new AutoBuilder_PersonBuilder(); } abstract PersonBuilder setName(String name); abstract PersonBuilder setId(int id); abstract Person build(); } ``` -------------------------------- ### Maven Configuration for AutoService Source: https://github.com/google/auto/blob/main/service/README.md Configure your Maven project to include auto-service-annotations as a compile-time dependency and auto-service as an annotation processor dependency. This setup ensures the metadata is generated during the build process. ```xml com.google.auto.service auto-service-annotations ${auto-service.version} ... maven-compiler-plugin com.google.auto.service auto-service ${auto-service.version} ``` -------------------------------- ### Un-serializable AutoValue Class Source: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/g3doc/index.md This example shows an AutoValue class that is not serializable because it contains java.util.Optional, which is not inherently serializable. ```java import java.io.Serializable; import java.util.Optional; import com.google.auto.value.AutoValue; @AutoValue public abstract class Foo implements Serializable { public static Foo create(Optional x) { return new AutoValue_Foo(x); } // java.util.Optional is not serializable. abstract Optional x; } ``` -------------------------------- ### Define AutoValue class with an un-serializable type Source: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/g3doc/serializer-extension.md This example shows an AutoValue class 'Foo' that contains a property 'bar' of an un-serializable type 'Bar'. This setup necessitates a custom SerializerExtension to make 'Foo' serializable. ```java import com.google.auto.value.AutoValue; import java.io.Serializable; @SerializableAutoValue @AutoValue public abstract class Foo implements Serializable { public static Foo create(Bar bar) { return new AutoValue_Foo(bar); } // Bar is unserializable. abstract Bar bar(); } // An un-serializable class. public final class Bar { public int x; public Bar(int x) { this.x = x; } } ``` -------------------------------- ### Generated Serializable Proxy Class Source: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/g3doc/serializer-extension.md This is an example of the code AutoValue generates for the `Foo` class after applying the `BarSerializerExtension`. It includes a `Proxy$` inner class that handles the serialization and deserialization logic for the `Bar` type. ```java @Generated("SerializableAutoValueExtension") final class AutoValue_Foo extends $AutoValue_Foo { Object writeReplace() throws ObjectStreamException { return new Proxy$(this.x); } static class Proxy$ implements Serializable { // The type is generated by {@code BarSerializer#proxyFieldType}. private int bar; Proxy$(Bar bar) { // The assignment expression is generated by {@code BarSerializer#toProxy}. this.bar = bar.x; } Object readResolve() throws ObjectStreamException { // The reverse mapping expression is generated by {@code BarSerializer#fromProxy}. return new AutoValue_Foo(new Bar(bar)); } } } ``` -------------------------------- ### Generic Class Example for Serialization Source: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/g3doc/serializer-extension.md This class demonstrates a generic type `T` that may or may not be serializable. The SerializerExtension can handle such cases by inspecting the type argument. ```java public final class Baz implements Serializable { public T x; public Baz(int x) { this.x = x; } } ``` -------------------------------- ### AutoBuilder Failure Due to Unavailable Parameter Names Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Example of an AutoBuilder interface that fails to compile because parameter names for the target static method ('LocalTime.of') are unavailable. ```java import java.time.LocalTime; public class TimeUtils { // Does not work, since parameter names from LocalTime.of are unavailable. @AutoBuilder(callMethod = "of", ofClass = LocalTime.class) public interface TimeBuilder { TimeBuilder setHour(int x); TimeBuilder setMinute(int x); TimeBuilder setSecond(int x); LocalTime build(); } } ``` -------------------------------- ### Nested AutoBuilder Example Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Illustrates how AutoBuilder generates a concrete subclass name when the `@AutoBuilder` type is nested within other classes. The generated name reflects the nesting hierarchy. ```java class Outer { static class Inner { @AutoBuilder abstract static class Builder {} } static Inner.Builder builder() { return new AutoBuilder_Outer_Inner_Builder(); } } ``` -------------------------------- ### Record Point with deprecated static factory method and InlineMe Source: https://github.com/google/auto/blob/main/value/userguide/records.md A Java record for Point that uses the @InlineMe annotation to guide migration of the deprecated static factory method. ```java package com.example.geometry; import com.google.errorprone.annotations.InlineMe; public record Point(int x, int y) { /** @deprecated Call the constructor directly. */ @Deprecated @InlineMe(replacement = "new Point(x, y)", imports = "com.example.geometry.Point") public static Point of(int x, int y) { return new Point(x, y); } } ``` -------------------------------- ### Handle JavaBeans Prefixes with Records Source: https://github.com/google/auto/blob/main/value/userguide/records.md When translating AutoValue classes to records, be aware that record field names might include 'get' prefixes if the original abstract methods were named like 'getName()'. This can affect reflection and debugger output. ```java public record Person(String getName, int getId) { public Person { Objects.requireNonNull(getName); } } ``` -------------------------------- ### Standard Builder Usage Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Demonstrates the conventional way to use an AutoBuilder for creating instances of a class. ```java Foo foo1 = Foo.builder().setBar(bar).setBaz(baz).build(); Foo.Builder fooBuilder = Foo.builder(); ``` -------------------------------- ### Java Usage of Person Builder Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Demonstrates how to use the generated PersonBuilder to create a Person instance. This approach abstracts away the constructor's parameter order. ```java Person p = PersonBuilder.personBuilder().setName("Priz").setId(6).build(); ``` -------------------------------- ### Generating a builder from an instance with static factory methods Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Provides static factory methods to create a builder from an existing instance or a new one. Useful when the built type has corresponding getter methods for all constructor/method parameters. ```java @AutoBuilder(ofClass = Person.class) abstract class PersonBuilder { static PersonBuilder personBuilder() { return new AutoBuilder_PersonBuilder(); } static PersonBuilder personBuilder(Person person) { return new AutoBuilder_PersonBuilder(person); } ... } ``` -------------------------------- ### Accumulating Collection Values (Works) Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md This demonstrates the correct way to accumulate values for a collection-valued property by first obtaining the builder for the collection, adding elements, and then building the final object. ```java Animal.Builder builder = Animal.builder() .setName("dog") .setNumberOfLegs(4); builder.countriesBuilder() .add("Guam") .add("Laos"); Animal dog = builder.build(); ``` -------------------------------- ### Use Step Builder to Create AutoValue Instance Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Instantiate an AutoValue object by following the defined steps, ensuring all properties are set in the correct order before calling build. ```java Stepped stepped = Stepped.builder().setFoo("foo").setBar("bar").setBaz(3).build(); ``` -------------------------------- ### Use AutoValue Builder to Create and Assert Animal Instances Source: https://github.com/google/auto/blob/main/value/userguide/builders.md Instantiate an Animal object using its builder, setting properties and calling build(). Assert the properties of the created object and compare it with other instances. The toString() method is also generated. ```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()); } ``` -------------------------------- ### Record Person class with validation in compact constructor Source: https://github.com/google/auto/blob/main/value/userguide/records.md The equivalent Java record for Person, incorporating the validation logic for 'id' and null check for 'name' into the compact constructor. ```java import java.util.Objects; public record Person(String name, int id) { public Person { Objects.requireNonNull(name, "name"); if (id <= 0) { throw new IllegalArgumentException("Id must be positive: " + id); } } } ``` -------------------------------- ### Handle Optional Properties in AutoValue Builders Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Demonstrates how to use `Optional` for properties, allowing them to default to an empty Optional and be set via `setFoo(Optional)` or `setFoo(String)`. ```java import com.google.auto.value.AutoValue; import java.util.Optional; @AutoValue public abstract class Animal { public abstract Optional name(); public static Builder builder() { return new AutoValue_Animal.Builder(); } @AutoValue.Builder public abstract static class Builder { // You can have either or both of these two methods: public abstract Builder setName(Optional value); public abstract Builder setName(String value); public abstract Animal build(); } } ``` -------------------------------- ### Usage of a 'Caller' Builder Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Shows how to use a builder designed to call a static method, emphasizing the 'call()' method instead of 'build()'. ```java logCaller().setLevel(Level.INFO).setMessage("oops").call(); ``` -------------------------------- ### Add toBuilder() Method to Value Class Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Implement the `toBuilder()` method in your abstract value class. AutoValue will provide the implementation, allowing callers to get a builder initialized with the current instance's property values. ```java public abstract Builder toBuilder(); ``` -------------------------------- ### Combine Set and Build Methods in Step Builder Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Optimize the step builder by combining the final property setting method with the build method. This reduces the number of calls required to create the object. ```java public interface BazStep { Stepped setBazAndBuild(int baz); } @AutoValue.Builder abstract static class Builder implements FooStep, BarStep, BazStep { abstract Builder setBaz(int baz); abstract Stepped build(); @Override public Stepped setBazAndBuild(int baz) { return setBaz(baz).build(); } } ``` -------------------------------- ### Implement Property Validation in Builder Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Split the build process into two methods: an abstract `autoBuild()` for AutoValue to implement and a concrete `build()` method that performs validation before returning the instance. This pattern is recommended for validating property values. ```java @AutoValue public abstract class Animal { public abstract String name(); public abstract int numberOfLegs(); public static Builder builder() { return new AutoValue_Animal.Builder(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setName(String value); public abstract Builder setNumberOfLegs(int value); abstract Animal autoBuild(); // not public public final Animal build() { Animal animal = autoBuild(); Preconditions.checkState(animal.numberOfLegs() >= 0, "Negative legs"); return animal; } } } ``` -------------------------------- ### Copy Annotations to Generated Field with @AutoValue.CopyAnnotations Source: https://github.com/google/auto/blob/main/value/userguide/howto.md Annotate a method within your @AutoValue class with @CopyAnnotations to copy its annotations to the corresponding generated field in the AutoValue_... implementation. This example shows copying @SuppressWarnings to the field and getter. ```java @Immutable @AutoValue abstract class Example { @CopyAnnotations @SuppressWarnings("Immutable") // justification ... abstract Object getObject(); // other details ... } ``` ```java final class AutoValue_Example extends Example { @SuppressWarnings("Immutable") private final Object object; @SuppressWarnings("Immutable") @Override Object getObject() { return object; } // other details ... } ``` -------------------------------- ### Implement a custom SerializerExtension for Bar Source: https://github.com/google/auto/blob/main/value/src/main/java/com/google/auto/value/extension/serializable/g3doc/serializer-extension.md This code demonstrates how to implement `SerializerExtension` to provide serialization and deserialization logic for the `Bar` type. It uses `@AutoService` for discoverability and defines how `Bar` maps to an `int` for serialization. ```java import com.google.auto.service.AutoService; import com.google.auto.value.extension.serializable.SerializableAutoValueExtension.Serializer; import com.google.auto.value.extension.serializable.SerializableAutoValueExtension.SerializerFactory; import com.google.auto.value.extension.serializable.SerializerExtension; import com.squareup.javapoet.CodeBlock; import java.util.Optional; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Types; import javax.lang.model.type.TypeKind; // Use AutoService to make BarSerializerExtension discoverable by java.util.ServiceLoader. @AutoService(SerializerExtension.class) public final class BarSerializerExtension implements SerializerExtension { // Service providers must have a public constructor with no formal parameters. public BarSerializerExtension() {} // This method is called for each property in an AutoValue. // When this extension can handle a type (i.e. Bar), we return a Serializer. called on all SerializerExtensions. @Override public Optional getSerializer( TypeMirror type, SerializerFactory factory, ProcessingEnvironment env) { // BarSerializerExtension only handles Bar types. if (!isBar(type)) { return Optional.empty(); } return Optional.of(new BarSerializer(env)); } // Our implementation of how Bar should be serialized + de-serialized. private static class BarSerializer implements Serializer { private final ProcessingEnvironment env; BarSerializer(ProcessingEnvironment env) { this.env = env; } // One way to serialize Bar is to just serialize Bar.x. // We can do that by mapping Bar to an int. @Override public TypeMirror proxyFieldType() { return Types.getPrimitiveType(TypeKind.INT); } // We need to map Bar to the type we declared in {@link #proxyFieldType}. // Note that {@code expression} is a variable of type Bar. @Override public CodeBlock toProxy(CodeBlock expression) { return CodeBlock.of("$L.x", expression); } // We need to map the integer back to a Bar. @Override public CodeBlock fromProxy(CodeBlock expression) { return CodeBlock.of("new $T($L)", Bar.class, expression); } } } ``` -------------------------------- ### Java Usage of Kotlin Builder Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Shows how to construct a KotlinData instance from Java code using the builder defined within the Kotlin class. It leverages default parameter values if setters are not explicitly called. ```java KotlinData k = KotlinData.builder().setLevel(23).build(); ``` -------------------------------- ### Handling Void Variants with @AutoOneOf Source: https://github.com/google/auto/blob/main/value/userguide/howto.md Demonstrates how to use @AutoOneOf when some variants have no associated data (void properties). This allows for distinct variants like NONE or CIRCLE_CROP without data, while others like BLUR can carry parameters. ```java @AutoOneOf(Transform.Kind.class) public abstract class Transform { public enum Kind {NONE, CIRCLE_CROP, BLUR} public abstract Kind getKind(); abstract void none(); abstract void circleCrop(); public abstract BlurTransformParameters blur(); public static Transform ofNone() { return AutoOneOf_Transform.none(); } public static Transform ofCircleCrop() { return AutoOneOf_Transform.circleCrop(); } public static Transform ofBlur(BlurTransformParmeters params) { return AutoOneOf_Transform.blur(params); } } ``` -------------------------------- ### AutoValue Builder with Optional Getters Source: https://github.com/google/auto/blob/main/value/CHANGES.md Demonstrates how to use Optional for getters in an AutoValue Builder. This allows for optional properties to be set or left empty. ```java abstract Optional name(); ``` -------------------------------- ### Builder for Calling Static Methods Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Illustrates an AutoBuilder configured to call a specific static method ('log' in this case) on a target class ('MyLogger'). ```java @AutoBuilder(callMethod = "log", ofClass = MyLogger.class) public abstract class LogCaller { public static LogCaller logCaller() { return new AutoBuilder_LogCaller(); } ... public abstract void call(); } ``` -------------------------------- ### Apache 2.0 License Source: https://github.com/google/auto/blob/main/service/README.md The AutoService project is licensed under the Apache License 2.0. This license governs the use, modification, and distribution of the software. ```text Copyright 2013 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` -------------------------------- ### Maven Configuration for AutoFactory Source: https://github.com/google/auto/blob/main/factory/README.md Include the `auto-factory` artifact as an optional dependency and in `annotationProcessorPaths` for Maven projects to enable code generation. ```xml com.google.auto.factory auto-factory ${auto-factory.version} true ... maven-compiler-plugin com.google.auto.factory auto-factory ${auto-factory.version} ``` -------------------------------- ### Implement 'with-' Methods for Immutable Updates Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Add 'with-' methods to your value class to create new instances with a single property changed. These methods typically delegate to `toBuilder()` and `build()`. ```java @AutoValue public abstract class Animal { public abstract String name(); public abstract int numberOfLegs(); public static Builder builder() { return new AutoValue_Animal.Builder(); } abstract Builder toBuilder(); public final Animal withName(String name) { return toBuilder().setName(name).build(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setName(String value); public abstract Builder setNumberOfLegs(int value); public abstract Animal build(); } } ``` -------------------------------- ### Generate Factory for a Class with Dependencies Source: https://github.com/google/auto/blob/main/factory/README.md Annotate a class with @AutoFactory to generate a JSR-330 compatible factory. Dependencies provided at construction time are handled by the factory, while parameters passed to the create method are passed directly to the class constructor. ```java @AutoFactory final class SomeClass { private final String providedDepA; private final String depB; SomeClass(@Provided @AQualifier String providedDepA, String depB) { this.providedDepA = providedDepA; this.depB = depB; } // … } ``` ```java import javax.annotation.Generated; import javax.inject.Inject; import javax.inject.Provider; @Generated(value = "com.google.auto.factory.processor.AutoFactoryProcessor") final class SomeClassFactory { private final Provider providedDepAProvider; @Inject SomeClassFactory( @AQualifier Provider providedDepAProvider) { this.providedDepAProvider = providedDepAProvider; } SomeClass create(String depB) { return new SomeClass(providedDepAProvider.get(), depB); } } ``` -------------------------------- ### Add AutoValue Dependencies (Gradle) Source: https://github.com/google/auto/blob/main/value/userguide/index.md Declare AutoValue dependencies in your build.gradle script. Use appropriate scopes for different project types. ```groovy dependencies { compileOnly "com.google.auto.value:auto-value-annotations:${autoValueVersion}" annotationProcessor "com.google.auto.value:auto-value:${autoValueVersion}" } ``` -------------------------------- ### Record Point class with primitive properties Source: https://github.com/google/auto/blob/main/value/userguide/records.md The equivalent Java record for the AutoValue Point class, initially retaining the static factory method for compatibility. ```java public record Point(int x, int y) { /** @deprecated Call the constructor directly. */ @Deprecated public static Point of(int x, int y) { return new Point(x, y); } } ``` -------------------------------- ### Fixing AutoBuilder with a Static Helper Method Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Demonstrates how to resolve AutoBuilder issues caused by unavailable parameter names by introducing a static helper method that AutoBuilder can reference. ```java import java.time.LocalTime; public class TimeUtils { static LocalTime localTimeOf(int hour, int minute, int second) { return LocalTime.of(hour, minute, second); } @AutoBuilder(callMethod = "localTimeOf") public interface TimeBuilder { TimeBuilder setHour(int x); TimeBuilder setMinute(int x); TimeBuilder setSecond(int x); LocalTime build(); } } ``` -------------------------------- ### Simplified Record Point class Source: https://github.com/google/auto/blob/main/value/userguide/records.md A more concise Java record for Point, omitting the static factory method once clients are updated. ```java public record Point(int x, int y) {} ``` -------------------------------- ### Fluent API for Adding Collection Elements Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md This shows how the public `addCountry` method allows for a fluent, chained API when adding elements to a collection-valued property, making the object construction more readable. ```java Animal dog = Animal.builder() .setName("dog") .setNumberOfLegs(4) .addCountry("Guam") .addCountry("Laos") // however many times needed .build(); ``` -------------------------------- ### Setting Default Values for Required Parameters Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Default values for parameters can be established by setting them in the builder() method before returning the builder. Parameters not annotated with @Nullable are required and will throw IllegalStateException if omitted. ```java class Foo { Foo(String bar, @Nullable String baz, String buh) {...} static Builder builder() { return new AutoBuilder_Foo_Builder() .setBar(DEFAULT_BAR); } @AutoBuilder interface Builder { Builder setBar(String x); Builder setBaz(String x); Builder setBuh(String x); Foo build(); } { builder().build(); // IllegalStateException, buh is not set builder().setBuh("buh").build(); // OK, bar=DEFAULT_BAR and baz=null builder().setBaz(null).setBuh("buh").build(); // OK builder().setBar(null); // NullPointerException, bar is not @Nullable } } ``` -------------------------------- ### Handle Nullable Properties in AutoValue Builders Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Shows how to use `@Nullable String` for properties, which default to null and can be set using a nullable setter, a non-nullable setter, or an `Optional` setter. ```java import com.google.auto.value.AutoValue; import java.util.Optional; import javax.annotation.Nullable; @AutoValue public abstract class Animal { public abstract @Nullable String name(); public static Builder builder() { return new AutoValue_Animal.Builder(); } @AutoValue.Builder public abstract static class Builder { // You can have either or both of these two methods: public abstract Builder setName(@Nullable String value); public abstract Builder setName(Optional value); public abstract Animal build(); } } ``` -------------------------------- ### Handle Collection Properties in AutoValue Builders Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Illustrates setting collection properties using Guava's immutable collections. The builder can accept various collection types like `Set`, `String...`, etc., which are then copied into an `ImmutableSet`. ```java import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableSet; import java.util.Set; @AutoValue public abstract class Animal { public abstract String name(); public abstract int numberOfLegs(); public abstract ImmutableSet countries(); public static Builder builder() { return new AutoValue_Animal.Builder(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setName(String value); public abstract Builder setNumberOfLegs(int value); public abstract Builder setCountries(Set value); public abstract Builder setCountries(String... value); public abstract Animal build(); } } ``` -------------------------------- ### Custom Build Method for ImmutableMap with buildKeepingLast Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Implement a workaround to use `buildKeepingLast` for an `ImmutableMap` within an AutoValue builder. This retains the last value for duplicate keys instead of throwing an exception. ```java @AutoValue public abstract class Foo { public abstract ImmutableMap map(); // #start // Needed only if your class has toBuilder() method public Builder toBuilder() { Builder builder = autoToBuilder(); builder.mapBuilder().putAll(map()); return builder; } abstract Builder autoToBuilder(); // not public // #end @AutoValue.Builder public abstract static class Builder { private final ImmutableMap.Builder mapBuilder = ImmutableMap.builder(); public ImmutableMap.Builder mapBuilder() { return mapBuilder; } abstract Builder setMap(ImmutableMap map); // not public abstract Foo autoBuild(); // not public public Foo build() { setMap(mapBuilder.buildKeepingLast()); return autoBuild(); } } } ``` -------------------------------- ### Add auto-value-annotations Dependency (Maven) Source: https://github.com/google/auto/blob/main/value/userguide/index.md Include this dependency in your pom.xml for compile-time classpath. Consider 'provided' scope for libraries. ```xml com.google.auto.value auto-value-annotations ${auto-value.version} ``` ```xml com.google.auto.value auto-value-annotations ${auto-value.version} provided ``` -------------------------------- ### Record Person class with non-primitive properties and null check Source: https://github.com/google/auto/blob/main/value/userguide/records.md The equivalent Java record for Person, including an explicit null check for the 'name' property in the compact constructor. ```java import java.util.Objects; public record Person(String name, int id) { public Person { Objects.requireNonNull(name, "name"); } } ``` -------------------------------- ### Implement Default Methods from Interfaces Source: https://github.com/google/auto/blob/main/value/userguide/howto.md Redeclare abstract methods that have default implementations in an interface to have AutoValue generate its own implementation. ```java @AutoValue class PleaseReimplementDefaultMethod implements InterfaceWithDefaultMethod { ... // cause AutoValue to implement this even though the interface has a default // implementation @Override public abstract int numberOfLegs(); } ``` -------------------------------- ### AutoBuilder with callMethod and ofClass Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Use when build() should call a specific static method of a specified class. The generated build() method will invoke LocalTime.of(...). ```java @AutoBuilder(callMethod = "of", ofClass = LocalTime.class) interface LocalTimeBuilder { ... LocalTime build(); // calls: LocalTime.of(...) } ``` -------------------------------- ### Generated Animal Implementation Source: https://github.com/google/auto/blob/main/value/userguide/generated-example.md This code is generated by AutoValue to provide a concrete implementation of the Animal class. It includes constructors, toString, equals, and hashCode methods. ```java import javax.annotation.Generated; @Generated("com.google.auto.value.processor.AutoValueProcessor") final class AutoValue_Animal extends Animal { private final String name; private final int numberOfLegs; AutoValue_Animal(String name, int numberOfLegs) { if (name == null) { throw new NullPointerException("Null name"); } this.name = name; this.numberOfLegs = numberOfLegs; } @Override String name() { return name; } @Override int numberOfLegs() { return numberOfLegs; } @Override public String toString() { return "Animal{" + "name=" + name + ", " + "numberOfLegs=" + numberOfLegs + "}"; } @Override public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof Animal) { Animal that = (Animal) o; return this.name.equals(that.name()) && this.numberOfLegs == that.numberOfLegs(); } return false; } @Override public int hashCode() { int h = 1; h *= 1000003; h ^= this.name.hashCode(); h *= 1000003; h ^= this.numberOfLegs; return h; } } ``` -------------------------------- ### Implement Public Add Method for Collection Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md To maintain a fluent API while accumulating collection values, keep the `propertyNameBuilder()` method non-public and implement a public `addPropertyName()` method that uses the internal builder. ```java import com.google.common.collect.ImmutableSet; @AutoValue public abstract class Animal { public abstract String name(); public abstract int numberOfLegs(); public abstract ImmutableSet countries(); public static Builder builder() { return new AutoValue_Animal.Builder(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setName(String value); public abstract Builder setNumberOfLegs(int value); abstract ImmutableSet.Builder countriesBuilder(); public final Builder addCountry(String value) { countriesBuilder().add(value); return this; } public abstract Animal build(); } } ``` -------------------------------- ### Handle Mutable Properties with Cloning and Warnings Source: https://github.com/google/auto/blob/main/value/userguide/howto.md If no immutable counterpart exists, clone mutable objects in the factory method and add a loud warning to the accessor method documentation, advising against mutation. ```java @AutoValue public abstract class MutableExample { public static MutableExample create(MutablePropertyType ouch) { // Replace `MutablePropertyType.copyOf()` below with the right copying code for this type return new AutoValue_MutableExample(MutablePropertyType.copyOf(ouch)); } /** * Returns the ouch associated with this object; do not mutate the * returned object. */ public abstract MutablePropertyType ouch(); } ``` -------------------------------- ### Inheritance-based StringOrInteger with @AutoValue Source: https://github.com/google/auto/blob/main/value/userguide/howto.md Demonstrates using inheritance with @AutoValue to create a class where only one of its properties is set. This approach is suitable when clients only need to access a common method. ```java public abstract class StringOrInteger { public abstract String representation(); public static StringOrInteger ofString(String s) { return new AutoValue_StringOrInteger_StringValue(s); } public static StringOrInteger ofInteger(int i) { return new AutoValue_StringOrInteger_IntegerValue(i); } @AutoValue abstract static class StringValue extends StringOrInteger { abstract String string(); @Override public String representation() { return '"' + string() + '"'; } } @AutoValue abstract static class IntegerValue extends StringOrInteger { abstract int integer(); @Override public String representation() { return Integer.toString(integer()); } } } ``` -------------------------------- ### Alternative to toBuilder() for Nested Objects Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Use an 'addAll' or 'putAll' method on the nested builder as an alternative to a 'toBuilder()' method on the nested object, similar to how ImmutableSet is handled. ```java ImmutableSet.Builder builder = ImmutableSet.builder(); builder.addAll(strings); ``` -------------------------------- ### Underride equals, hashCode, or toString Source: https://github.com/google/auto/blob/main/value/userguide/howto.md Provide your own implementations of equals, hashCode, or toString in the abstract class. AutoValue will detect these and skip generating its own, inheriting your logic. ```java @AutoValue class PleaseOverrideExample extends SuperclassThatDefinesToString { ... // cause AutoValue to generate this even though the superclass has it @Override public abstract String toString(); } ``` -------------------------------- ### AutoBuilder with neither callMethod nor ofClass Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Use when build() should call a constructor of the containing class. The generated build() method will invoke new Person(name, id). ```java class Person { Person(String name, int id) {...} @AutoBuilder interface Builder { ... Person build(); // calls: new Person(name, id) } } ``` -------------------------------- ### Define Step Builder Interfaces for AutoValue Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Use a collection of builder interfaces to enforce a step-by-step property setting process at compile time. This ensures all required properties are set before building. ```java @AutoValue public abstract class Stepped { public abstract String foo(); public abstract String bar(); public abstract int baz(); public static FooStep builder() { return new AutoValue_Stepped.Builder(); } public interface FooStep { BarStep setFoo(String foo); } public interface BarStep { BazStep setBar(String bar); } public interface BazStep { Build setBaz(int baz); } public interface Build { Stepped build(); } @AutoValue.Builder abstract static class Builder implements FooStep, BarStep, BazStep, Build {} } ``` -------------------------------- ### AutoBuilder with only ofClass Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Use when build() should call a constructor of a specified class. The generated build() method will invoke new Thread(...). ```java @AutoBuilder(ofClass = Thread.class) interface ThreadBuilder { ... Thread build(); // calls: new Thread(...) } ``` -------------------------------- ### AutoValue Generated Animal Class with Builder Source: https://github.com/google/auto/blob/main/value/userguide/generated-builder-example.md This snippet demonstrates the structure of a class generated by AutoValue, including the implementation of abstract methods from the Animal interface and a nested builder class. The builder handles property setting and validation before building the final immutable object. ```java import javax.annotation.Generated; @Generated("com.google.auto.value.processor.AutoValueProcessor") final class AutoValue_Animal extends Animal { private final String name; private final int numberOfLegs; private AutoValue_Animal( String name, int numberOfLegs) { this.name = name; this.numberOfLegs = numberOfLegs; } @Override String name() { return name; } @Override int numberOfLegs() { return numberOfLegs; } @Override public String toString() { return "Animal{" + "name=" + name + ", " + "numberOfLegs=" + numberOfLegs + "}"; } @Override public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof Animal) { Animal that = (Animal) o; return (this.name.equals(that.name())) && (this.numberOfLegs == that.numberOfLegs()); } return false; } @Override public int hashCode() { int h = 1; h *= 1000003; h ^= this.name.hashCode(); h *= 1000003; h ^= this.numberOfLegs; return h; } static final class Builder extends Animal.Builder { private String name; private Integer numberOfLegs; Builder() { } @Override Animal.Builder setName(String name) { if (name == null) { throw new NullPointerException("Null name"); } this.name = name; return this; } @Override Animal.Builder setNumberOfLegs(int numberOfLegs) { this.numberOfLegs = numberOfLegs; return this; } @Override Animal build() { String missing = ""; if (this.name == null) { missing += " name"; } if (this.numberOfLegs == null) { missing += " numberOfLegs"; } if (!missing.isEmpty()) { throw new IllegalStateException("Missing required properties:" + missing); } return new AutoValue_Animal( this.name, this.numberOfLegs); } } } ``` -------------------------------- ### Implement annotation type with AutoAnnotation Source: https://github.com/google/auto/blob/main/value/userguide/howto.md Use @AutoAnnotation to programmatically create annotation instances when needed. This is useful for generating 'fake' annotation instances. ```java public @interface Named { String value(); } public class Names { @AutoAnnotation public static Named named(String value) { return new AutoAnnotation_Names_named(value); } } ``` -------------------------------- ### Define Abstract Animal Value Class with Builder Source: https://github.com/google/auto/blob/main/value/userguide/builders.md Define an abstract value class and a nested abstract builder class. AutoValue generates implementations for both. Ensure the static builder() method is in the value class, not the nested builder class, to avoid initialization-order issues. ```java import com.google.auto.value.AutoValue; @AutoValue abstract class Animal { abstract String name(); abstract int numberOfLegs(); static Builder builder() { // The naming here will be different if you are using a nested class // e.g. `return new AutoValue_OuterClass_InnerClass.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(); } } ``` -------------------------------- ### Configure Maven Compiler Plugin for AutoValue Source: https://github.com/google/auto/blob/main/value/userguide/index.md Configure the maven-compiler-plugin in your pom.xml to use AutoValue as an annotation processor. ```xml maven-compiler-plugin com.google.auto.value auto-value ${auto-value.version} ``` -------------------------------- ### Annotate Service Implementation with @AutoService Source: https://github.com/google/auto/blob/main/service/README.md Annotate your service implementation class with @AutoService, specifying the service interface. This signals AutoService to generate the necessary metadata. ```java package foo.bar; import com.google.auto.service.AutoService; import javax.annotation.processing.Processor; @AutoService(Processor.class) final class MyProcessor implements Processor { // … } ``` -------------------------------- ### AutoBuilder with only callMethod Source: https://github.com/google/auto/blob/main/value/userguide/autobuilder.md Use when build() should call a static method of the containing class. The generated build() method will invoke Foo.concat(first, middle, last). ```java class Foo { static String concat(String first, String middle, String last) {...} @AutoBuilder(callMethod = "concat") interface ConcatBuilder { ... String build(); // calls: Foo.concat(first, middle, last) } } ``` -------------------------------- ### Add auto-common Dependency to Maven Project Source: https://github.com/google/auto/blob/main/common/README.md Include this dependency in your Maven project to use the auto-common utilities. Replace '1.0-SNAPSHOT' with a known release version if available. ```xml com.google.auto auto-common 1.0-SNAPSHOT ``` -------------------------------- ### Handle Nested Immutable Objects without AutoValue Source: https://github.com/google/auto/blob/main/value/userguide/builders-howto.md Requirements for nested immutable classes that are not AutoValue, such as protobufs. They must provide a way to create a builder and build an instance. ```java // Requirements for nested class: // 1. Way to make a new builder (e.g., new Species.Builder(), Species.builder(), Species.newBuilder()). // 2. Builder must have a build() method. // 3. If toBuilder() is needed, Species must have a toBuilder() method. ```