Java Keywords Addendum: The Java Record
record
keyword. Introduced in Java 14, the purpose of this keyword is to eliminate all the boilerplate code when creating a Java POJO. For example,
public class Student {
private String name;
private int id;
public Student(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(int id) {
this.id = id;
}
}
public record Student(String name, int id){ }
Object#equals(Object)
, Object#hashCode()
, and Object#toString()
.
Usage
Here is a simpe example of a record declaration as a .java file.
Student.java
public record Student(String name, int id){ }
Main.java
public class Main {
public static void main(String[] args) {
Student s1 = new Student("John", 1);
Student s2 = new Student("Mary", 2);
Student s3 = new Student("Hector", 3);
Student s4 = s2;
System.out.println("Student 1's name: " + s1.name());
System.out.println("Student 2's id: " + s2.id());
System.out.println("Student 3: " + s3);
System.out.println("Student 2 is equal to 4: " + s2.equals(s4));
}
}
record
is a class
. It is a class without boilerplate code. A much more simplified form of a class. It does have caveats, which are outlined in the "Restrictions" section below.
Another thing you should notice is that the getter methods do not have the prefix "get" in them. It is a direct derivation of the variable name. Is this a good thing or a bad thing? I am somewhat neutral, but leaning towards this convention. I am an old developer who is quite used to the getter/setter naming convention. But even I know this can get somewhat confusing when it comes to boolean fields. It seems to me that the developer community is almost split in the middle when it comes to the prepending boolean getter methods with "is" versus "get". To me, not prepending seems more sensible. Simpler. If you want to know the getter method name for a particular field, simply look for that field in the constructor.
The output of this example is as shown below:
Student 1's name: John
Student 2's id: 2
Student 3: Student[name=Hector, id=3]
Student 2 is equal to 4: true
Object#toString()
method. The fourth print out statement illustrate the use of the implementation of Object#equals(Object)
and Object#hashCode()
. All of that packaged in this simple record declaration
public record Student(String name, int id){ }
Object#equals(Object)
and Object#hashCode()
, and then override Object#toString()
. It took me seconds to create the records.
Restrictions
There are some caveats that you must be aware when using records.- Java
records
cannot be extended. They are implicitlyfinal
. For this reason, they cannot beabstract
. - Java
records
are immutable. Therefore, their inner values cannot be changed after instantiation. - Because
records
are immutable, they contain no setter methods. Values must be passed through the constructor
record
. This means that they are inherently thread-safe. This benefit makes it easier to share this object across mulitple threads without worrying about changing internal values, proper ways to synchronize, slowing down the application when applying locks, etc. However, with every benefit, there are some drawbacks. For example, if the data being held by the object changes frequently, this means you will need to create a new record each and every time the data changes which can present challenges when garbage collecting. As a developer, it is up to you to decide what is the best approach for your application. In some cases, using records will greatly improve your application. In other cases, it might be of a hinderance to use them. Arm yourself with what you learn here and decide for yourself.
I hope this short article was of some benefit to you. For my next topic, I will get into customizing Java records and implementing interfaces with records. Good luck and stay tuned!
Comments
Post a Comment