Java 14 record Syntax seems alien
Diego Vieira Vivo
diego.vivo at gmail.com
Wed Apr 15 05:04:56 UTC 2020
Dear all,
I’m sending this email to provide comments on the new Java 14 Record syntax.
This new feature is very welcome, but the Kotlin syntax seems alien in
Java, no other type declaration has parenthesis and arguments.
I’d like to propose a syntax closer to the one for Java interfaces as shown
below
public record Product{
String name;
String description;
BigDecimal price;
}
The fields who be automatically private final as in the record type preview
today.
The type would have a default implicit constructor with all arguments,
that could be made explicit (similar to the the implicit no arg constructor
in a Java class)
Type annotations and field annotations would be applicable similar to how
they are used.
In a more complete example
@Embeddable
@ValueObject
public record Product{
@NotEmpty
@Column
@Unique
String sku;
@NotEmpty
@Column
String name;
@NotEmpty
@MyAnnotation
String description;
@Positive
BigDecimal price;
// implicit arguments could be made explicit by developer see note
below
public Product {
if (!description.contains(“MyBrand”)){
throw new IllegalArgumentException(“Description does
not contain MyBrand”);
}
}
Note on the constructor
For more readability if the developer choose the args can be made explicit
(all being final)
If the arguments are explicit declared the developer must also do de value
assignment.
public Product(final String sku, final String name, final String
description, final BigDecimal price){
this.sku = sku.toUpperCase();
this.name = name.toUpperCase();
this.price = price;
this.description = description;
// added the validation after the assignment to keep all the
assignments as initial statements
if (!description.contains(“MyBrand”)){
throw new IllegalArgumentException(“Description does
not contain MyBrand”);
}
}
This gives power to the developer extend and define the final behavior.
And just to convey my point this approach of having implicit defaults is
already part of java, specifically to provide a example from constructors,
the implicit super() call in the first line of the constructor that can be
made explicit or replaced by another super constructor call like
super(anArgument);
The goal is to start as simple as
public record Product{
String name;
String description;
BigDecimal price;
}
And allow the developer to expand (just as we see in enums)
This was my main point and I’d be happy if you have it in your
consideration for this feature.
Other points I’d like to bring are:
1. Even if all the methods should be overridable, some hints/keywords or
annotations to not use a field in the generated methods would be a good
addition.
Because the developer may want to omit a field from the toString because it
may contain sensitive information or GDPR information, and toStrings are
usually dumped in the logs as is.
Also in the equals and hashcode, sometimes the record contain a field that
should be ignored, like a event timestamp or some metadata that is
informational and should not be used to check equality from a business rule
perspective.
The only concern I would be developer creating record entities ignoring all
properties and just considering the Id for equals and hashcode (commonly
used when having Lombok ) and based on what I saw I believe that is not the
intention of the Record JSR.
2. Some type annotation and some META-INF/“record” config file to set the
naming strategy of the getter/accessor
Just for the sake of backwards compatibility with the old naming convention.
So old code would be able to call getName() in a record instead of being
force to call name, the developer would be empowered to decide if he or she
would keep consistency or not.
Thank you very much for the work you have been doing
I wish you all the best.
Best Regards,
Diego Vivo.
P.S.: Stay Safe
--
Diego Vieira Vivo
More information about the amber-dev
mailing list