
Java was never known for being an expressive language. If we look back in history, handy features such as lambda expression have been there long before – in other languages such as C#, for example. Especially writing data classes such as DTOs or model classes – without the IDE auto-generate feature for constructors and getter/setters, this would have been a real pain. But autogenerated code also has its drawbacks – it needs to be maintained, and it can be changed and is not really “clean” as we always have to look for manual changes. We, as developers, love to automate things – this is where Lombok comes into play. It helps us with a lot of routine work, as mentioned above. But wait, data classes – wasn’t there a JVM language with native support for that? Of course, Kotlin comes to rescue. So there are already a lot of alternatives to writing more efficient code. But with the new release cycle of Java, a lot of new features “borrowed” from other languages such as Kotlin make their way faster to the regular Java language without the need for third-party library support. One of these upcoming features in Java 14 will be the native support for data classes. Let’s have a look – shorting a data class from > 30 LOC to 1 – without any libraries.
Let’s start coding
Let’s imagine we want to have a user data class with three attributes – ID, firstName, and lastName. The “plain” old Java way would look like this:
package io.viesure.java14.preview.model; public class UserJavaWay { int userId; String firstName; String lastName; public UserJavaWay(int userId, String firstName, String lastName) { this.userId = userId; this.firstName = firstName; this.lastName = lastName; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
Nothing special. A lot of boilerplate code. Let’s introduce Lombok for comparison:
package io.viesure.java14.preview.model; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @Getter @Setter @AllArgsConstructor(access = AccessLevel.PUBLIC) public class UserLombok { private int userId; private String firstName; private String lastName; }
Looks far better. We managed to shorten the class significantly, but it has some drawbacks. We need a third-party library for it, and we need to enable annotation processing: nothing evil but room for improvement. This is where Java14 records come to shine. Let’s have a look at the Java14 native solution with records:
package io.viesure.java14.preview.model; public record UserJava14 (int userId, String firstName, String lastName) { }
And this is where the new magic comes in. Java will automatically generate everything we need to have a proper data class. Behind the scenes, the class looks like this:
package io.viesure.java14.preview.model; public final class UserJava14 extends java.lang.Record { private final int userId; private final java.lang.String firstName; private final java.lang.String lastName; public UserJava14(int userId, java.lang.String firstName, java.lang.String lastName) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int userId() { /* compiled code */ } public java.lang.String firstName() { /* compiled code */ } public java.lang.String lastName() { /* compiled code */ } }
Besides, as expected, all getter and setter have been generated. There are also hashCode(), equals(), and a toString() method. Everything we need with just one line of Java Code. If you want to have a look at the full power of this feature you can find it here (https://openjdk.java.net/jeps/359)
Hint: If you also want to have a look at your generated classes go to your compiled class files within your target folder and use javap command e.g., javap UserJava14
You need to install Java 14 (https://jdk.java.net/14/). If you do not want to use the command line to compile your files, IntelliJ EAP already supports most of the Java 14 Features (https://www.jetbrains.com/idea/nextversion)
Summary
Java is getting more and more handy features and syntactic sugar. Keep in mind that Records are still a preview feature and therefore are not ready for production in any way. But in general, the direction in which Java as a language is heading it getting it closer and closer to developer loved programming languages such as Kotlin (see https://www.youtube.com/watch?v=te3OU9fxC8U for which features may get from Kotlin to Java). There are a lot of new upcoming features (e.g., https://blog.jetbrains.com/idea/2020/03/java-14-and-intellij-idea/) in the next years, which will make the task of programming more straight forward and the code easier to maintain.