As you can see, we have to make the class final so that it can’t be subclassed (has to do with equality guarantees), make our fields private, use getters to retrieve the values, and add a constructor so that users can create Money objects. This turned our simple little 4 line class into 14 lines.

But we’re not done yet. Equality is still by reference. This means that $2 != $2. We need to implement equals(), and also hashCode() if we ever want to use this object in a set, or as keys in a map.

To implement hashCode() and equals() I’ve simply asked IntelliJ to create them for me, which is great as long as I don’t change fields. This has also turned my not-so-little 14 line class into a full grown 29 line class.

But what happens if we want to log this object? Surely we’d like something a little better than Money@12CE469 to show up in our logs. Therefore we need to add a toString() method.

And now we’ve gone from 4 lines to 34 lines in this class. If you believe in the relationship between lines of code and potential for bugs, then you see the problem here, to say nothing of the extra work required to create and manage this thing.

AutoValue to the Rescue

This is where AutoValue comes in. It’s an annotation processor that generates all of the mundane value-type code for you, so you can focus on more important things.

To add AutoValue to your project, you simply need to add it’s single dependency to your annotation processing classpath. Being in the annotation processing classpath means that no dependencies of AutoValue get added to your final artifact, only the generated code.

123

dependencies{apt'com.google.auto.value:auto-value:1.2-rc1'}

To use AutoValue to turn our Money object into a full fledged value type, you simply need to add an annotation to the now abstract class.

Behind the scenes, AutoValue generates all of the private fields, the constructor, hashCode(), equals(), and toString() for you. This generated class, named by simply prefixing your class name with AutoValue_, is package private, so all you or your users ever really deal with is the annotated Money class.

Since the subclass’s constructor is package private, you also need to add static factory methods, Item 1 in Josh Bloch’s Effective Java, to create your objects.

With that we’re done. This value class is effectively identical to the previous example, but is contained in 7 lines of code, and only contains what we need.

One feature that shows the benefit of AutoValue’s method of subclassing is that you can add any additional code to the class you want. So, for instance, if you have derived fields, they can be added to the Money class without the need for helper classes.

Testing: The Hidden Benefit

One benefit of generated code is that it doesn’t need to be tested. Whereas in the earlier example all of the code would need to be tested to guard against regressions and ensure proper functionality, with AutoValue, since the generator itself has been tested and is known to produce correct code, we don’t have to worry about testing all of the boilerplate code.

Extensions

So now that you can easily create value types in Java, what if you want to use your generated value types with other systems, like JSON serializers, or Android’s Parcel class? That’s where extensions come in.

With the release of AutoValue 1.2-rc1, we finally have support for AutoValue Extensions. With Extensions you can have additional functionality, in most cases simply by adding a dependency to your annotation processor classpath.

For example, say you wanted your Money object above to be Parcelable. By simply adding the AutoValue: Parcel Extension to your annotation processing classpath and making your class implement Parcelable, the generated code will be Parcelable.