immutable value class を生成してくれるライブラリ。abstract クラスを用意して @AutoValue をつけると、equals() や hashCode() などの boilerplate なコードを実装したクラスを用意してくれる。
設定
dependencies {
compile 'com.google.auto.value:auto-value:1.2'
apt 'com.google.auto.value:auto-value:1.2'
}
使い方
例えば
@AutoValue
abstract class Animal {
abstract String name();
abstract int numberOfLegs();
}
のようなクラスを定義すると、AutoValue_Animalというクラスが生成される。
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;
}
}
コンスタクタでは name と numberOfLegs を引数に取り、equals() や hasCode() ではこれらを使った実装になっている。
immutable value class なのでコンスタクタで受け取った引数は final として保持される。
abstract クラスに static な生成メソッドを用意して利用する。
@AutoValue
abstract class Animal {
static Animal create(String name, int numberOfLegs) {
return new AutoValue_Animal(name, numberOfLegs);
}
abstract String name();
abstract int numberOfLegs();
}
コンスタクタの引数は null チェックされる。これを止めたいときは abstract メソッドの戻り値に @Nullable をつける。
@AutoValue
abstract class Animal {
@Nullable
abstract String name();
abstract int numberOfLegs();
}
final class AutoValue_Animal extends Animal {
private final String name;
private final int numberOfLegs;
AutoValue_Animal(
@Nullable String name,
int numberOfLegs) {
this.name = name;
this.numberOfLegs = numberOfLegs;
}
...
}
Builder を用意することも可能。@AutoValue をつけるクラスにインナークラスとして abstract static な Builder クラスを定義し、@AutoValue.Builder をつける。
@AutoValue
abstract class Animal {
abstract String name();
abstract int numberOfLegs();
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();
}
}
final class AutoValue_Animal extends Animal {
...
static final class Builder extends Animal.Builder {
private String name;
private Integer numberOfLegs;
Builder() {
}
Builder(Animal source) {
this.name = source.name();
this.numberOfLegs = source.numberOfLegs();
}
@Override
public Animal.Builder name(String name) {
this.name = name;
return this;
}
@Override
public Animal.Builder numberOfLegs(int numberOfLegs) {
this.numberOfLegs = numberOfLegs;
return this;
}
@Override
public Animal build() {
String missing = "";
if (name == null) {
missing += " name";
}
if (numberOfLegs == null) {
missing += " numberOfLegs";
}
if (!missing.isEmpty()) {
throw new IllegalStateException("Missing required properties:" + missing);
}
return new AutoValue_Animal(
this.name,
this.numberOfLegs);
}
}
}