Thursday 13 October 2022

Why don't record classes follow the Java Bean conventions?

Records are named tuples1.

Notice that the name of the field accessors does not start with get and, therefore, does not conform to the JavaBeans conventions.

We can declare getter methods if we really want to, and let them refer to the record method, but I'd opt not to if possible. We can do it, for a little while, until frameworks catch up to the new code convention, which will be pretty quick.

As Brian Goetz wrote in an online thread2:

“. . . the language has a responsibility to look forward as well as backward, and balance the needs of existing code with the needs of new code. Taking a bad library naming convention and burning it into the language forever would have been the worse choice.”

Builders

We can create builders for Records, if we like. See [3] for instance, but I'm not a fan of automatic code generation.

FreeMarker

The reason I started on this blog, is because there's a plethora of different frameworks/tools/what-have-you available that all center around the Java Beans conventions.

In most cases, records are not a good fit for these, as those frameworks and tools operate on the notion that these are mutable data classes.

But sometimes, there are definitely simple use cases where it would come in handy.

For example with the use of Freemarker4, a templating engine that converts your templates and Java POJOs to nice html pages (or other kinds of pages, there's no limit really).

And these follow the getX() convention.

So, one way would be to create the blasted getter methods in the Record class, but then you're adding boilerplate again, and I feel uncomfortable with that.

Perhaps an idea is to create my own DefaultObjectWrapper5.

So, Freemarker will need some changes to support record classes6. Something like automatically generating a hashmap of all the methods that have no arguments, yet return something... and preferable do not start with get?

References

[1] Data Classes and Sealed Types for Java - Brian Goetz February 2019
https://openjdk.java.net/projects/amber/design-notes/records-and-sealed-classes
[2] ForumPost - Feedback for records: Accessors name() vs. getName()
https://mail.openjdk.java.net/pipermail/amber-dev/2020-August/006414.html
[3] GitHub - RecordBuilder
https://github.com/Randgalt/record-builder
[4] FreeMarker
https://freemarker.apache.org/
[5] FreeMarker - Object wrappers
https://freemarker.apache.org/docs/pgui_datamodel_objectWrapper.html#pgui_datamodel_defaultObjectWrapper
[6] Apache JIRA - FREEMARKER-183
https://issues.apache.org/jira/browse/FREEMARKER-183
JLS - 8.10. Record Classes
https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-8.10
JavaMagazine - Records Come to Java
https://blogs.oracle.com/javamagazine/post/records-come-to-java
JavaMagazine - Java records: Serialization, marshaling, and bean state validation
https://blogs.oracle.com/javamagazine/post/diving-into-java-records-serialization-marshaling-and-bean-state-validation

No comments:

Post a Comment