cannot be corrupted ➤ Simple to construct, test and use ➤ No need of a copy constructor or clone method ➤ Hashcode can use lazy initialization ➤ Good Map/Set keys 4
1 data //then somewhere in the task class void delay(int delayDays) { _startDate.setDate(_startDate.getDate() + delayDays); // somewhere else task2.delay(5); // now you find task1's start date has changed 5
Immutable and Final ➤ No Accessible constructors ➤ Don’t allow to change internal mutable objects ➤ No use of identity-sensitive operations ➤ Substitutable when equals 7
final class Area { private final long longitude; private final long latitude; private final float radius; public Area(long longitude, long latitude, float radius) { this.longitude = longitude; this.latitude = latitude; this.radius = radius; } } 10
final class Area { private final long longitude; private final long latitude; private final float radius; public Area(long longitude, long latitude, float radius) { this.longitude = longitude; this.latitude = latitude; this.radius = radius; } public long getLongitude() { return longitude; } public long getLatitude() { return latitude; } public float getRadius() { return radius; } } 11
public abstract long latitude(); public abstract long longitude(); public abstract float radius(); public static Area create(long latitude, long longitude, float radius) { return new AutoValue_Area(latitude, longitude, radius); } } ➤ AutoValue_Area Generated at Compile Time 18
long latitude(); public abstract long longitude(); public abstract float radius(); public static Builder builder() { return new AutoValue_Area.Builder(); } @AutoValue.Builder public abstract static class Builder { public abstract Builder setLatitude(long latitude); public abstract Builder setLongitude(long longitude); public abstract Builder setRadius(float radius); public abstract Area build(); } } 19
all toString, equals, etc ➤ Minimal impact on method count ➤ Can use Builders ➤ Generated class means Debugger is usable ➤ Checks for Null Objects (use @Nullable) ➤ Don’t use mutable objects or wrap them ➤ Awesome documentation 20
{ public abstract long latitude(); public abstract long longitude(); public abstract float radius(); public static Area create(long latitude, long longitude, float radius) { return new AutoValue_Area(latitude, longitude, radius); } } Installation apt ‘com.ryanharter.auto.value:auto-value-parcel:0.2.5' https://github.com/rharter/auto-value-parcel 23
abstract long latitude(); public abstract long longitude(); public abstract float radius(); public abstract Area withLatitude(long latitude); } Installation apt 'com.gabrielittner.auto.value:auto-value-with:1.0.0' https://github.com/gabrielittner/auto-value-with 24
} @AutoValue public abstract class Area { public abstract long latitude(); public abstract long longitude(); @Redacted public abstract float radius(); public static Area create(long latitude, long longitude, float radius) { return new AutoValue_Area(latitude, longitude, radius); } } E/AUTOVALUE: Redacted message, Area{latitude=75, longitude=75, radius=██} ➤ Installation apt 'com.squareup.auto.value:auto-value-redacted:1.0.1' ➤ https://github.com/square/auto-value-redacted
public abstract long latitude(); @SerializedName("longitude") public abstract long longitude(); @SerializedName("radius") public abstract float radius(); public static TypeAdapter<Area> typeAdapter(Gson gson) { return new AutoValue_Area.GsonTypeAdapter(gson); } } Installation apt 'com.ryanharter.auto.value:auto-value-gson:0.4.6' provided 'com.ryanharter.auto.value:auto-value-gson:0.4.6' https://github.com/rharter/auto-value-gson 26
abstract long latitude(); public abstract long longitude(); @ColumnName("area_radius") public abstract float radius(); public static Area create(Cursor cursor) { return AutoValue_Area.createFromCursor(cursor); } } ➤ Installation apt 'com.gabrielittner.auto.value:auto-value-cursor:1.0.1' compile 'com.gabrielittner.auto.value:auto-value-cursor-annotations:1.0.1' ➤ https://github.com/gabrielittner/auto-value-cursor
@FirebaseAdapter(LocationAdapter.class) public abstract Location location(); public abstract float radius(); public static Area create(Location location, float radius) { return new AutoValue_Area(location, radius); } public static Area create(DataSnapshot dataSnapshot){ return dataSnapshot.getValue(AutoValue_Area.FirebaseValue.class).toAutoValue(); } public Object toFirebaseValue(){ return new AutoValue_Area.FirebaseValue(this); } } ➤ Add two methods Create and toFirebaseValue ➤ For non default values, use adapters
➤ Less code written -> less bugs ➤ Easy refactoring and object manipulation ➤ No “Oups I forgot to modify this toString” ➤ Somewhat faster de/serialization ➤ Somewhat slower compile time ➤ Thread safety