Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Java 14 Records for generic (non-data) classes with only final fields [closed]

Given a simple class with a final field, such as a String (see example below) or Spring dependencies, is a good idea to use a Java 14 record to make it more concise and possibly remove annotation processors such as Lombok?

According to the JEP describing records, "Records make the semantic claim of being simple, transparent holders for their data".

Obviously, a generic class with only final fields, is not exactly a transparent holder for its data, and when using a record, its final variables are exposed, which may not be desirable. However, in many cases it is probably not a major problem.

Therefore, is this "enough" to consider it an "abuse" of this language feature? Or are there any other, less obvious drawbacks?

@RequiredArgsConstructor // or an explicit constructor when not using lombok
class AudienceValidator implements OAuth2TokenValidator<Jwt> {
    private final String audience;

    public OAuth2TokenValidatorResult validate(Jwt jwt) {
        // validate
    }
}


record AudienceValidator(String audience) implements OAuth2TokenValidator<Jwt> {

    public OAuth2TokenValidatorResult validate(Jwt jwt) {
        // validate
    }
}
like image 246
user140547 Avatar asked Dec 31 '22 04:12

user140547


1 Answers

It depends on the intended semantics here, but based on what I see here, it is probably an abuse. Is an AudienceValidator its state and nothing but its state? Does all its behavior derive from its state (the way a norm() method would derive from the real and imaginary parts of a Complex)?

The best way to think about records is they are nominal tuples, that can be enhanced with behavior. (A useful analogy: Java enums are to C enums, as records are to structural tuples.) That seems to not be what you are doing here, and so clients would be rightfully confused to see this class in an API exposed as a record, but behaving otherwise.

You might well ask "but, why wouldn't I take advantage of this language feature to make writing this class easier?" You can of course do as you like, but reading code is more important than writing code. Deliberately using the wrong feature because it's easier places the writer's convenience over that of the reader.

like image 194
Brian Goetz Avatar answered Jan 02 '23 18:01

Brian Goetz