auto(Goodle AutoValue)
google AutoValue
Google AutoValue
一个 Java 不可变数据类型的代码生成库,用于帮我们生成 Bean 的 getter()
,hashCode()
,equals()
,toString()
,注意没有 setter()
开源项目主页
https://github.com/google/auto
官网文档:
https://github.com/google/auto/blob/master/value/userguide/index.md
Why use AutoValue?
https://github.com/google/auto/blob/master/value/userguide/why.md
生成的 immutable,没有 setter 方法,怎么修改?
简单用法
添加 dependencies
1
2
| provided 'com.google.auto.value:auto-value:1.2'
apt 'com.google.auto.value:auto-value:1.2'
|
创建一个 abstract
类使用 @AutoValue
作用于类上
1
2
3
4
5
| @AutoValue
public abstract class Story {
public abstract int id();
public abstract String title();
}
|
使用 @AutoValue
注解后,AutoValue
会生成一个 AutoValue_你的类名
为名称的类并继承你写的抽象类,这个类是 包级私有
的,他里面有私有的成员变量,对应的构造函数,以及重写的 hashCode()
、equals()
和 toString()
方法。由于这个生成的子类是包级私有的,所以这里在给 Story 提供构造方法的时候需要提供一个静态的构造方法。
[生成 Builder 代码]
- 编写 builder() 方法,返回
new AutoValue_*.Builder();
具体根据你的实体名字修改 - 编写 Builder 类:
- 使用
@AutoValue.Builder
注解 abstract static class Builder
类 - 在类中必须要有一个方法
abstract T build();
将 T 改为你的实体。 - 在类中用
abstract Builder 变量名(变量类型 value)
这样的形式声明你所有的参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| @AutoValue
public 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();
}
}
|
使用
1
| Animal animal = Animal.builder().name("dog").numberOfLegs(4).build();
|
注意
类必须是 abstract
,并且只能是带有返回值的无参数的 abstract
的方法,返回值不能是 void,也不能带有参数。修饰符不能为 private
1
2
3
4
| // 带有参数的
abstract String name(int age);
// 返回值为void的
abstract void haha();
|
equals(
)、hashCode()
和 toString()
如果你想要实现你自己版本的这些方法(或其中之一),你可以在注解类中自己实现,AutoValue 会识别出来并不产生代码,你的实现也会被继承并在 final 类中被使用
生成的类
- 生成类继承了添加注解的抽象类,生成的类是 final 的,而且带有
AutoValue_
前缀。 - 如果你想要在添加注解的类中访问生成的代码的话,这一点很重要。因为这样就像通过静态工厂方法访问构造器。
- 该类是包间私有的。因此在其他包里无法看到生成的类,当然,它也不应该在其他类中被使用。
- 该类构造器也是包间私有的,将所有参数作为属性
- 构造器中对传入的参数作了判断,所有属性都不会是空。如果你想让某个属性为空,不妨添加一个
@Nullable
注解
1
2
3
4
| @AutoValue
public abstract class User {
@Nullable public abstract String middleName();
}
|
- 成员变量真的没什么特别的,唯一要说的就是数据域都是 final,以保证类型不变性。
AutoValue Extension API
Reference
使用 Google AutoValue 自动生成代码
http://www.jianshu.com/p/0e2be3536a4e
深入研究 AutoValue
https://github.com/hehonghui/android-tech-frontier/blob/master/issue-49/深入研究AutoValue.md
auto-service
auto-service
https://github.com/google/auto/tree/master/service
使用
1
2
| 'com.google.auto.service:auto-service:1.0-rc2'
'com.squareup:javapoet:1.8.0'
|
在你的 Processor 上添加 @AutoService(Processor.class)
1
2
3
4
5
6
7
8
| package foo.bar;
import javax.annotation.processing.Processor;
@AutoService(Processor.class)
final class MyProcessor extends Processor {
// …
}
|
会在 src/main/
生成 META-INF/services/javax.annotation.processing.Processor
1
| me.hacket.BindViewProcessor
|