Autovalue

Autovalue or simple POJO

Intention:

Try com.google.auto.value, is it really useful?

Description:


I had a discussion about boilerplate code and its impact on the readability/component weight/unit test coverage.

Is it really useful?  
Below is listed a simple example of a bean annotated with AutoValue, which during build phase automatically entire bean + it's builder is generated with equals/hashcode/toString.

package eca.test.wrappers;
import com.google.auto.value.AutoValue;
import com.google.common.base.Optional;
@AutoValue
public abstract class RequestWrapper {
public abstract String getName();
public abstract String getSurname();
abstract public Optional<String> getPhone();
abstract public Optional<String> getGroup();
public static Builder builder() {
return new AutoValue_RequestWrapper.Builder()
.setPhone(Optional.<String>absent())
.setGroup(Optional.<String>absent());
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setName(String value);
public abstract Builder setSurname(String value);
abstract Builder setPhone(Optional<String> value);
public Builder setPhone(String value) {
return setPhone(Optional.fromNullable(value));
}
abstract Builder setGroup(Optional<String> value);
public Builder setGroup(String value) {
return setGroup(Optional.fromNullable(value));
}
public abstract RequestWrapper build();
}
}
view raw AutoValue.java hosted with ❤ by GitHub
package eca.test.wrappers;
import com.google.common.base.Optional;
import javax.annotation.Generated;
@Generated("com.google.auto.value.processor.AutoValueProcessor")
final class AutoValue_RequestWrapper extends RequestWrapper {
private final String name;
private final String surname;
private final Optional<String> phone;
private final Optional<String> group;
private AutoValue_RequestWrapper(
String name,
String surname,
Optional<String> phone,
Optional<String> group) {
if (name == null) {
throw new NullPointerException("Null name");
}
this.name = name;
if (surname == null) {
throw new NullPointerException("Null surname");
}
this.surname = surname;
this.phone = phone;
this.group = group;
}
@Override
public String getName() {
return name;
}
@Override
public String getSurname() {
return surname;
}
@Override
public Optional<String> getPhone() {
return phone;
}
@Override
public Optional<String> getGroup() {
return group;
}
@Override
public String toString() {
return "RequestWrapper{"
+ "name=" + name + ", "
+ "surname=" + surname + ", "
+ "phone=" + phone + ", "
+ "group=" + group
+ "}";
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof RequestWrapper) {
RequestWrapper that = (RequestWrapper) o;
return (this.name.equals(that.getName()))
&& (this.surname.equals(that.getSurname()))
&& ((this.phone == null) ? (that.getPhone() == null) : this.phone.equals(that.getPhone()))
&& ((this.group == null) ? (that.getGroup() == null) : this.group.equals(that.getGroup()));
}
return false;
}
@Override
public int hashCode() {
int h = 1;
h *= 1000003;
h ^= name.hashCode();
h *= 1000003;
h ^= surname.hashCode();
h *= 1000003;
h ^= (phone == null) ? 0 : phone.hashCode();
h *= 1000003;
h ^= (group == null) ? 0 : group.hashCode();
return h;
}
static final class Builder extends RequestWrapper.Builder {
private String name;
private String surname;
private Optional<String> phone;
private Optional<String> group;
Builder() {
}
Builder(RequestWrapper source) {
this.name = source.getName();
this.surname = source.getSurname();
this.phone = source.getPhone();
this.group = source.getGroup();
}
@Override
public RequestWrapper.Builder setName(String name) {
this.name = name;
return this;
}
@Override
public RequestWrapper.Builder setSurname(String surname) {
this.surname = surname;
return this;
}
@Override
public RequestWrapper.Builder setPhone(Optional<String> phone) {
this.phone = phone;
return this;
}
@Override
public RequestWrapper.Builder setGroup(Optional<String> group) {
this.group = group;
return this;
}
@Override
public RequestWrapper build() {
String missing = "";
if (name == null) {
missing += " name";
}
if (surname == null) {
missing += " surname";
}
if (!missing.isEmpty()) {
throw new IllegalStateException("Missing required properties:" + missing);
}
return new AutoValue_RequestWrapper(
this.name,
this.surname,
this.phone,
this.group);
}
}
}

Conclusion:


In case the model is really simple it might be useful, but when it has variation of references/nulable/ or custom validation than I would say it does not bring a lot of value.

References:

Git: https://github.com/ecararus/autovalue
Documentation: https://github.com/google/auto/tree/master/value