Closed TrackerSB closed 3 years ago
This is in the same class as other recent discussions/comments. I'm open to doing this but I'd make it configurable. Should the configuration be global i.e. as a -A
to javac? What should the default be? Should the option be in the annotation itself - i.e. add an attribute to RecordBuilder
like boolean emptyDefaultForOptional()
? What should the default for that be?
I can imagine multiple approaches that allow specifying default values for fields if these are wanted:
emptyDefaultForOptional
to the RecordBuilder
annotation as you say.
This would be pretty straight forward and would solve the case for me but that's not a general solution for the problem of specifying default values of any type.public record Foo(
@DefaultBuilderValue("Optional.empty()")
Optional<String> bar) {
}
Allowing to specify "random init code" for a field as a String
would somehow "solve" the problem of defining default values but I expect it to introduce too much complexity and too many problems with type safety.
public record Foo(Optional<String> bar){
private static Optional<String> initBar(){
return Optional.empty();
}
}
This would allow to specify default values for any field if wanted with any code and for any type. However it would introduce a dependency on correct naming of methods. It would also introduce a problem with type safety since the return type of the method and type of the field have to match. Additionally it would require access to private methods via reflection. This approach would further not allow to specify that "all Optional
fields should be initialized with Optional.empty()
". You would have to specify an init method for each field that should default to Optional.empty()
.
public record Foo(Optional<String> bar) {
public Foo() {
bar = Optional.empty();
}
}
Here specifying default values for desired fields would be very compact but it requires a developer to introduce a default constructor if there are any fields that should have a specific default value and requires the generated builder to create a default constructed record and use its values as init values for its own fields.
public record Foo(Optional<String> bar) {
public Foo {
if( bar == null ) {
bar = Optional.empty();
}
}
}
This would not require any changes to RecordBuilder
but it is not nice in the sense that the values of the record are internally "corrected" at its creation and therefore would basically disallow certain values for fields instead of introducing default values in the builder for them.
So I think that a general solution for specifying default values would introduce in any case quite some complexity.
Note this PR will begin to allow RecordBuilder to support more customizations without sacrificing simplicity for the normal user: https://github.com/Randgalt/record-builder/pull/37
Currently the fields of a generated builder are initialized with Java default values. Thus if one had a field of type
Optional<SomeFancyClass>
its initial value would benull
whereasOptional.empty()
may be a preferable initial value.