AutoValue是Google几个工程师写的一个小的java实体类生成工具,可以让你拜托繁琐而且容易出错的字段判断,下面对这个工具进行如下说明,maven的配置信息,依赖包导入:
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value-annotations</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<version>1.6</version>
<scope>provided</scope>
</dependency>
申明要生成的Java类的相关信息:
@AutoValue
abstract public class User {
static User create(String name, int age, String address){
return new AutoValue_User(name, age, address);
}
abstract public String name();
abstract public int age();
abstract public String address();
}
生成class文件的反编译的信息
final class AutoValue_User extends User {
private final String name;
private final int age;
private final String address;
AutoValue_User(String name, int age, String address) {
if (name == null) {
throw new NullPointerException("Null name");
} else {
this.name = name;
this.age = age;
if (address == null) {
throw new NullPointerException("Null address");
} else {
this.address = address;
}
}
}
public String name() {
return this.name;
}
public int age() {
return this.age;
}
public String address() {
return this.address;
}
public String toString() {
return "User{name=" + this.name + ", age=" + this.age + ", address=" + this.address + "}";
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof User)) {
return false;
} else {
User that = (User)o;
return this.name.equals(that.name()) && this.age == that.age() && this.address.equals(that.address());
}
}
public int hashCode() {
int h$ = 1;
int h$ = h$ * 1000003;
h$ ^= this.name.hashCode();
h$ *= 1000003;
h$ ^= this.age;
h$ *= 1000003;
h$ ^= this.address.hashCode();
return h$;
}
}
在这里需要注意的是:
- 实体类中AutoValue的前缀不能改变,否则编译不会通过;
- 字段名称必须对应一致,实际参数列表和形参列表一致,否则编译不过;
可以使用builder模式
@AutoValue
abstract class User2 {
abstract public String name();
abstract public int age();
abstract public String address();
static Builder builder() {
return new AutoValue_User2.Builder();
}
@AutoValue.Builder
abstract static class Builder {
abstract Builder setName(String name);
abstract Builder setAge(int age);
abstract Builder setAddress(String address);
abstract User2 build();
}
}
生成代码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
final class AutoValue_User2 extends User2 {
private final String name;
private final int age;
private final String address;
private AutoValue_User2(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String name() {
return this.name;
}
public int age() {
return this.age;
}
public String address() {
return this.address;
}
public String toString() {
return "User2{name=" + this.name + ", age=" + this.age + ", address=" + this.address + "}";
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof User2)) {
return false;
} else {
User2 that = (User2)o;
return this.name.equals(that.name()) && this.age == that.age() && this.address.equals(that.address());
}
}
public int hashCode() {
int h$ = 1;
int h$ = h$ * 1000003;
h$ ^= this.name.hashCode();
h$ *= 1000003;
h$ ^= this.age;
h$ *= 1000003;
h$ ^= this.address.hashCode();
return h$;
}
static final class Builder extends User2.Builder {
private String name;
private Integer age;
private String address;
Builder() {
}
User2.Builder setName(String name) {
if (name == null) {
throw new NullPointerException("Null name");
} else {
this.name = name;
return this;
}
}
User2.Builder setAge(int age) {
this.age = age;
return this;
}
User2.Builder setAddress(String address) {
if (address == null) {
throw new NullPointerException("Null address");
} else {
this.address = address;
return this;
}
}
User2 build() {
String missing = "";
if (this.name == null) {
missing = missing + " name";
}
if (this.age == null) {
missing = missing + " age";
}
if (this.address == null) {
missing = missing + " address";
}
if (!missing.isEmpty()) {
throw new IllegalStateException("Missing required properties:" + missing);
} else {
return new AutoValue_User2(this.name, this.age, this.address);
}
}
}
}
这种方式的优点:其申明的Java类是final型,不可改变;对于一些字段的详细的判断,例如为空,或者类型的判断不需要我们再写额外的代码,具有良好的判断,你不在需要担心bean里边产生bug;而且如果bean中的字段较多时,,这种方式的优势尤为明显。
凡是有利就有弊,对待所有的东西都要有一个辩证的看待,不能盲目地崇拜。
缺点:在使用一些框架的时候可能这种方式是不太合适的,比较mybatis,spring MVC等这一类需要进行反射映射字段的时候,这种方式就不行了;而且从上面的代码中我们可以看出其默认是不生成无参的构造函数的,这在有些情况下也是不能使用的。
在这种方式中也可以使用集合属性、optional,在builder模式下可以相关阈值进行限制,比如年龄大于0才能够进行build操作等等,相关更加详细的说明参考