We all have worked with Value Classes in our projects. A value type is simply an immutable object whose equality is based on property values, as opposed to identity. For example, let’s create a class with data for Employee. There are some properties in this class that can be accessed using a getter. This class also overrides equals(Object), toString(), hashCode() and this is a very common pattern for any project. Here is the sample of Employee class. The sample project can be found on GitHub.
As you can see in the above example that there are 50-60 lines of code for a common class and there are many classes like this in the project. The problem with this code is the maintenance, analysis, and review. When there is a need to add one more attribute; we must take several steps like- declare a parameter, include it in the constructor, create a getter for that attribute, add that attribute in equals(Object), hashCode() and toString() method. If there is some mistake during the process the whole code will fail when while accessing this class. There is a library to overcome this problem and it also goes ahead and provides a Parcelable implementation, so that we don’t have to implement it ourselves.
The above problem can be overcome with Google’s solution to the value type issue i.e AutoValue. The above lengthy class can be converted into a more concise class that will contain 10-20 lines of code. The developer only needs to declare a class and all the other heavy work is taken care of by AutoValue. Let’s see how we can set up AutoValue in our Android Studio.
1. Add the following dependency to your build.gradle file-
2. Add @AutoValue annotation to that class.
3. Make the class abstract since its implementation will be generated, and can not be created manually.
4. Remove the earlier attributes and implement abstract methods in that class corresponding to the attributes.
After these steps, your class should look like this-
Looks great, isn’t it?
As now we have our class as abstract so we must define a way to create an instance of it. AutoValue class allows new instance by publishing a static method create.
Note: AutoValue classes are generated during build time. You must rebuild your project every time you make any changes in the definitions.
At some point, using constructor with several parameters might become unmanageable. Don’t worry, AutoValue allows Builder pattern as well. That means we can generate classes that allow the initialization of objects using the Builder Pattern. To create a Builder, we must define an internal abstract class, as the sample below.
Now replace the create method by the builder() method, written as below-
Now we can create class as-
Our class is now much simpler. We can now declare new attribute very easily with no hassle.
The AutoValue also has a very useful feature called AutoValue Extensions. There are many extensions that AutoValue supports. For example-
We just need to add the below-mentioned dependency to support Parcelable classes.
Now we just have to make our EmployeeData class implement Parcelable. All the methods for this interface will be generated by the extension, the developer doesn’t need to write any more code.
AutoValue is the only solution to the value class problem in Java having characteristics like-
- No runtime dependencies
- Negligible cost to performance
- Very few limitations on what your class can do
Below is an excerpt mentioned in the official documentation-
“AutoValue is a great tool for eliminating the drudgery of writing mundane value classes in Java. It encapsulates much of the advice in Effective Java Chapter 2 and frees you to concentrate on the more interesting aspects of your program. The resulting program is likely to be shorter, clearer, and freer of bugs. Two thumbs up.”
— Joshua Bloch, author, Effective Java