When using AutoValue with the Builder pattern, how can I initialize other custom final fields in the constructor?
Example
@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();
}
}
in the real-world class the initialisation (like in the `fullPath field) is more expensive, so that I want to do it only once. I see 2 ways to do this:
1) lazy initialisation
private Path fullPath;
Path getFullPath() {
if (fullPath == null) {
fullPath = Paths.get(directory(), fileName(), fileExt());
}
return fullPath;
}
2) initalisation in the builder
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;
}
is there another alternative, so that the fullPath
field can be final?
You could simply have a Builder method that takes the full path and use a default value:
@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();
}
}
}
This should be pretty safe since the constructor will be made private so there should be no situation in which an instance can be created without going through the build()
method path unless you create your own static factory methods, in which case you can do the same thing.