Value Class Generated by FreeBuilder
FreeBuilder 是一个非常好用的基于 JAVA 注解处理器 APT (Annotation Processing Tool) 技术的数据实体类生成器,可以 通过简单的注解来生成 Builder 模式的实体类。AutoValue 是另一个非常好用的基于 APT 的类库,参见 Value Class Generated by Google AutoValue。二者的区别在于:
- AutoValue 根据开发者提供的一个 Builder 接口来实现具体的 Builder 类;FreeBuilder 则对给定的数据实体类生成符合固定规则的 Builder 类。前者可以控制生成的 Builder 类的方法列表,后者无法控制生成的 Builder 类的方法列表,但是可以通过继承生成的 Builder 类限制对外暴露的方法列表。
- AutoValue 需要数据实体类是一个抽象类;FreeBuilder 则同时支持抽象类和接口。
详细对比可以参考 FreeBuilder Alternatives 。
🔗Maven Settings
<dependency> <groupId>org.inferred</groupId> <artifactId>freebuilder</artifactId> <version>${freebuilder_version}</version> <scope>provided</scope> </dependency>
freebuilder
中同时包含了定义数据实体类时需要的注解和注解处理器实现。
截至 2019-09-30 日, FreeBuilder 的最新版本是 2.4.1
。
🔗Abstract Class
一个基本的数据类如下:
@FreeBuilder interface Task { Long id(); String type(); String description(); static Builder builder() { return new Builder(); } class Builder extends Task_Builder { } }
上述是所需要的全部代码。如果倾向于使用抽象类的话,可以换成:
@FreeBuilder abstract class Task { abstract long getId(); abstract String getType(); abstract String getDescription(); static Builder builder() { return new Builder(); } static class Builder extends Task_Builder { } }
定义一个数据实体类,只需提供一个接口或抽象类,所需字段以接口方法/抽象方法声明即可,FreeBuilder 会通过 APT 生成一个名为 Task_Builder
的 Builder 类和两个分别名为 Task_Builder.Value
和 Task_Builder.Partial
的实现类。以上生成类的类名是由实体类名自动生成的。
每一个接口方法/抽象方法会被 FreeBuilder 标记为一个 property :如果方法名以 "get" 开头则对应的 property 名是方法名去掉 "get" 之后的部分,否则是整个方法名。
🔗Builder
FreeBuilder 会在 Task_Builder
中为 Task
中的每一个 property 生成一系列的方法。
🔗Regular Property
对于基本类型和普通类类型的 property 如 long getId()
,会生成:
方法 | 说明 |
---|---|
setId(long) | Setter |
getId() | Getter |
mapId(UnaryOperator | Mutator |
示例如下:
@Generated("org.inferred.freebuilder.processor.Processor") abstract class Task_Builder { // ... public Task.Builder setId(long id) { // ... } public Task.Builder mapId(UnaryOperator<Long> mapper) { // ... } public long getId() { // ... } // ... }
🔗Property of Optional Type
对于 Optional
(java.util.Optional
或 com.google.common.base.Optional
) 类型的 property 如 Optional<String> getTitle()
,会生成:
方法 | 说明 |
---|---|
setTitle(String) | Setter with non-null value |
setTitle(Optional | Setter with optional value |
setNullableTitle(String) | Setter with nullable value |
getTitle() | Getter |
mapTitle(Spliterator | Mutator |
clearTitle() | Setter with Optional.empty() |
示例如下:
public StudentDto.Builder setTitle(String title) { // ... } public StudentDto.Builder setTitle(Optional<? extends String> title) { // ... } public StudentDto.Builder setNullableTitle(String title) { // ... } public StudentDto.Builder mapTitle(UnaryOperator<String> mapper) { // ... } public StudentDto.Builder clearTitle() { // ... } public Optional<String> getTitle() { // ... }
🔗Property of Collection Type
对于 List
, Set
, SortedSet
和 Multiset
类型的 property 如 List<String> getEmails()
,会生成:
方法 | 说明 |
---|---|
addEmails(String) | Appends a single value |
addEmails(String ...) | Appends multi values |
addAllEmails(Iterable | Appends all elements from a java.lang.Iterable |
addAllEmails(Spliterator | Appends all elements from a java.util.Spliterator |
addAllEmails(Stream | Appends all elements from a java.util.stream.Stream |
mutateEmails(Consumer<List | Mutates values by invoking a java.util.function.Consumer |
clearEmails() | Remove all elements |
getEmails() | Returns an unmodifiable view of all elements |
示例如下:
public StudentDto.Builder addEmails(String element) { // ... } public StudentDto.Builder addEmails(String... elements) { // ... } public StudentDto.Builder addAllEmails(Spliterator<? extends String> elements) { // ... } public StudentDto.Builder addAllEmails(BaseStream<? extends String, ?> elements) { // ... } public StudentDto.Builder addAllEmails(Iterable<? extends String> elements) { // ... } public StudentDto.Builder mutateEmails(Consumer<? super List<String>> mutator) { // ... } public StudentDto.Builder clearEmails() { // ... } public List<String> getEmails() { // ... }
🔗Property of Map Type
对于 Map
类型的 property 如 Map<String, Integer> getScores()
,会生成:
方法 | 说明 |
---|---|
putScores(String, Integer) | Adds a key-value pair |
putAllScores(Map<String, Integer>) | Adds key-value pairs from an existed map |
removeScores(String) | Removes a pair with given key |
mutateScores(Consumer<Map<String, Integer>>) | Mutator |
clearScores() | Removes all pairs |
getScores() | Returns an unmodifiable view of all pairs |
示例如下:
public StudentDto.Builder putScores(String key, int value) { // ... } public StudentDto.Builder putAllScores(Map<? extends String, ? extends Integer> map) { // ... } public StudentDto.Builder removeScores(String key) { // ... } public StudentDto.Builder mutateScores(Consumer<? super Map<String, Integer>> mutator) { // ... } public StudentDto.Builder clearScores() { // ... } public Map<String, Integer> getScores() { // ... }
🔗Custom Propertys Generation
FreeBuilder 会自动生成数据实体类的 String toString()
方法和 boolean equals(Object)
;方法实现中会默认包含所有的 property 。
如果某个 property 不想被包含在 toString
方法中,可以对其添加 @NotInToString
注解。
如果某个 property 不想被包含在 equals
方法中,可以对其添加 @IgnoredByEquals
注解。
完整的示例代码可以参见 FreeBuilder Usecases 。
FreeBuilder 是这样的强大,以至于我正在使用它逐步替换 AutoValue 。
以上。