AutoValue 1.0 released by Google

Google has released the first stable version of its AutoValue library. AutoValue is an open source library for easily creating value types with Java. AutoValue is part of a Google project that goes by the name of auto on GitHub. This project is described as “a collection of source code generators for Java.”

What are value types? In a nutshell, a value-typed object is an object without an identity, i.e. two value objects are considered equal if their respective internal state is equal. Value objects are typically immutable. Prominent examples for value types are monetary values or date objects.

Writing an implementation for a value type in Java is typically repetitive, tedious and error-prone. To help Java developers adhere to the DRY principle, Google provides its AutoValue library which generates the full source code of your value objects for you. All you have to do is to define an abstract specification of the value type. AutoValue will then do the rest for you by generating a concrete implementation of your specification. This implementation contains all the bells and whistles that are necessary for properly implemented value objects: a sensible implementation for hashCode, equals, and toString, a constructor that checks preconditions, and all necessary getter methods. Because value objects are immutable, no setters will be generated.

AutoValue runs as a code generator. After having defined your value type specification, an annotation processor kicks in during compilation and creates the full implementation class for you.

This approach has several advantages. It is debugger friendly, since you can easily step into the implementation of the generated code in a debugging session, so no proxy layers obfuscate the insight into a running application. Plus your code doesn’t depend on any byte code manipulation framework and you don’t need to add any additional runtime dependency. All you need to do to use AutoValue is to define the following dependencies in your project:

<dependency>
  <groupId>com.google.auto.value</groupId>
  <artifactId>auto-value</artifactId>
  <version>1.0</version>
  <scope>provided</scope>
</dependency>

Now let’s have a look at a concrete example of how to use AutoValue. A popular example in the space of immutable value objects are complex numbers. So let’s create a complex number value type. Here’s our specification for that class:

import com.google.auto.value.AutoValue;

@AutoValue
public abstract class Complex {

    public static Complex createFromCartesian(double real, double imaginary) {
        return new AutoValue_Complex(real, imaginary);
    }

    public static Complex createFromPolar(double r, double theta) {
        return new AutoValue_Complex(r * Math.cos(theta), r * Math.sin(theta));
    }

    public abstract double getReal();
    public abstract double getImaginary();
}

We write an abstract class Complex and annotate that with @AutoValue. Next we define an abstract getter method for every field we want to expose with the interface of our value type. In our example, this is the real and imaginary part of the complex number. To create new instances of the value type, we define one or more static factory methods. In the case of complex numbers, we want to provide the options to create new objects either with cartesian or polar representation. It is important not to expose the generated implementation of the value object. Therefore, the factory methods return our abstract specification class.

When this class is compiled the first time, the AutoValue library creates the following implementation class AutoValue_Complex:

import javax.annotation.Generated;

@Generated("com.google.auto.value.processor.AutoValueProcessor")
final class AutoValue_Complex extends Complex {

  private final double real;
  private final double imaginary;

  AutoValue_Complex(
      double real,
      double imaginary) {
    this.real = real;
    this.imaginary = imaginary;
  }

  @Override
  public double getReal() {
    return real;
  }

  @Override
  public double getImaginary() {
    return imaginary;
  }

  @Override
  public String toString() {
    return "Complex{"
        + "real=" + real + ", "
        + "imaginary=" + imaginary
        + "}";
  }

  @Override
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (o instanceof Complex) {
      Complex that = (Complex) o;
      return (Double.doubleToLongBits(this.real) == Double.doubleToLongBits(that.getReal()))
           && (Double.doubleToLongBits(this.imaginary) == Double.doubleToLongBits(that.getImaginary()));
    }
    return false;
  }

  @Override
  public int hashCode() {
    int h = 1;
    h *= 1000003;
    h ^= (Double.doubleToLongBits(real) >>> 32) ^ Double.doubleToLongBits(real);
    h *= 1000003;
    h ^= (Double.doubleToLongBits(imaginary) >>> 32) ^ Double.doubleToLongBits(imaginary);
    return h;
  }
}

As you can see, that’s quite a bit of code you don’t have to write yourself and – most important of all – you don’t have to debug yourself.

There’s one caveat: since this class is only generated when you compile, you will first get a compile-time error when referencing AutoValue_Complex in the factory methods, since this class doesn’t exist at first. This is fixed, though, after the first compiler run.

Besides this core feature of AutoValue, there are some more things the library allows you to do:

  • data hiding through non-public accessor methods
  • nullability of fields with @Nullable
  • arbitrarily named property accessors (e.g. real() instead of getReal())
  • other preconditions and preprocessing
  • custom implementations of equals, hashCode or toString
  • nesting of value objects
  • derived fields

You can read about them in more detail on the AutoValue GitHub page.

Short URL for this post: http://wp.me/p4nxik-2ii
Roland Krüger

About Roland Krüger

Software Engineer at Orientation in Objects GmbH. Find me on Google+, follow me on Twitter.
This entry was posted in Did you know?, Java and Quality and tagged , , . Bookmark the permalink.

One Response to AutoValue 1.0 released by Google

  1. Java Fluid says:

    Excellent article on AutoValue & its usage. I have used this library at work & I see lot of value to the code.

    thanks @Roland for bringing this.

    View source code at http://www.lookatsrc.com/source/com/google/auto/value/AutoValue.java?a=com.google.auto.value:auto-value

Leave a Reply