使用 Builder 为 AutoValue 自定义最终字段
custom final field for AutoValue with Builder
在构建器模式中使用 AutoValue 时,如何在构造函数中初始化其他自定义最终字段?
例子
@AutoValue
abstract class PathExample {
static Builder builder() {
return new AutoValue_PathExample.Builder();
}
abstract String directory();
abstract String fileName();
abstract String fileExt();
Path fullPath() {
return Paths.get(directory(), fileName(), fileExt());
}
@AutoValue.Builder
interface Builder {
abstract Builder directory(String s);
abstract Builder fileName(String s);
abstract Builder fileExt(String s);
abstract PathExample build();
}
}
在现实世界中 class 初始化(就像在 `fullPath 字段中)更昂贵,所以我只想做一次。我看到有 2 种方法可以做到这一点:
1) 惰性初始化
private Path fullPath;
Path getFullPath() {
if (fullPath == null) {
fullPath = Paths.get(directory(), fileName(), fileExt());
}
return fullPath;
}
2) 在构建器中初始化
private Path fullPath;
Path getFullPath() {
return fullPath;
}
@AutoValue.Builder
abstract static class Builder {
abstract PathExample autoBuild();
PathExample build() {
PathExample result = autoBuild();
result.fullPath = Paths.get(result.directory(), result.fileName(), result.fileExt());
return result;
}
是否有另一种选择,以便 fullPath
字段可以 final?
您可以简单地使用一个采用完整路径并使用默认值的 Builder 方法:
@AutoValue
abstract class PathExample {
static Builder builder() {
return new AutoValue_PathExample.Builder();
}
abstract String directory();
abstract String fileName();
abstract String fileExt();
abstract Path fullPath();
@AutoValue.Builder
interface Builder {
abstract Builder directory(String s);
abstract Builder fileName(String s);
abstract Builder fileExt(String s);
abstract Builder fullPath(Path p);
abstract PathExample autoBuild();
public PathExample build() {
fullPath(Paths.get(directory(), fileName(), fileExt()));
return autoBuild();
}
}
}
这应该是非常安全的,因为构造函数将被设为私有,因此不存在不通过 build()
方法路径就可以创建实例的情况,除非您创建自己的静态工厂方法,在这种情况下你可以做同样的事情。
在构建器模式中使用 AutoValue 时,如何在构造函数中初始化其他自定义最终字段?
例子
@AutoValue
abstract class PathExample {
static Builder builder() {
return new AutoValue_PathExample.Builder();
}
abstract String directory();
abstract String fileName();
abstract String fileExt();
Path fullPath() {
return Paths.get(directory(), fileName(), fileExt());
}
@AutoValue.Builder
interface Builder {
abstract Builder directory(String s);
abstract Builder fileName(String s);
abstract Builder fileExt(String s);
abstract PathExample build();
}
}
在现实世界中 class 初始化(就像在 `fullPath 字段中)更昂贵,所以我只想做一次。我看到有 2 种方法可以做到这一点:
1) 惰性初始化
private Path fullPath;
Path getFullPath() {
if (fullPath == null) {
fullPath = Paths.get(directory(), fileName(), fileExt());
}
return fullPath;
}
2) 在构建器中初始化
private Path fullPath;
Path getFullPath() {
return fullPath;
}
@AutoValue.Builder
abstract static class Builder {
abstract PathExample autoBuild();
PathExample build() {
PathExample result = autoBuild();
result.fullPath = Paths.get(result.directory(), result.fileName(), result.fileExt());
return result;
}
是否有另一种选择,以便 fullPath
字段可以 final?
您可以简单地使用一个采用完整路径并使用默认值的 Builder 方法:
@AutoValue
abstract class PathExample {
static Builder builder() {
return new AutoValue_PathExample.Builder();
}
abstract String directory();
abstract String fileName();
abstract String fileExt();
abstract Path fullPath();
@AutoValue.Builder
interface Builder {
abstract Builder directory(String s);
abstract Builder fileName(String s);
abstract Builder fileExt(String s);
abstract Builder fullPath(Path p);
abstract PathExample autoBuild();
public PathExample build() {
fullPath(Paths.get(directory(), fileName(), fileExt()));
return autoBuild();
}
}
}
这应该是非常安全的,因为构造函数将被设为私有,因此不存在不通过 build()
方法路径就可以创建实例的情况,除非您创建自己的静态工厂方法,在这种情况下你可以做同样的事情。