Records were first introduced in Java 14.
What is Java Records?
Records in Java are a concise way to define immutable classes. They focus on data storage and offer:
Automatic boilerplate code: The compiler generates getters, equals, hashCode, and toString methods for you.
Immutability by default: Record fields are final, promoting thread safety and simplifying reasoning about your data.
public record Person(String name, int age) {
// No need to explicitly declare constructors,
//getters, toString, hashCode, or equals.
}
From this one line of code, the compiler generates the following:
final fields with a String name and int age
A constructor which sets both the fields with the value (canonical constructor)
the accessor methods name() and age()
an equals() method that evaluates if two instances are the same if name and age values are the same for both instances
a hashcode() method returns the same hashcode for two same instances
a toString() method
We can use the record Person defined above as we use a normal Java class.
Person p = new Person("Ram",12);// using Canonical Constructor
System.out.println(p);//using ToString
System.out.println(p.name());// using getter
System.out.println(p.hashCode()); //using hashCode()
Person p2 = new Person("Ram", 12);
System.out.println(p.equals(p2));//using equals()
Static fields in Records
Records can be extended by static (final or non-final) fields. For Example:
public record Person(String name, int age) {
public static final int DEFAULT_AGE = 0;
public static String DEFAULT_NAME = "RAJ";
}
Canonical Constructor Overriding
public record Person(String name, int age) {
public Person(String name, int age) {
System.out.println("Accessing the Canonical Constructor");
this.name = name;
this.age = age;
}
}
Compact Constructor
There is another concise way of overriding the canonical constructor which is called compact constructor.
public record Person(String name, int age) {
public Person {
System.out.println("Accessing the Compact Constructor");
}
}
Methods in Records
we can also define the static and non-static methods.
public record Person(String name, int age) {
public void hello(){
System.out.println("hello");
}
public static void bye(){
System.out.println("Bye");
}
}
Inheritance in Records
Records can implement interfaces but cannot extend classes and since Records are implicitly final they cannot inherit from them also.
public interface Base {
int age();
}
public record Person(String name, int age) implements Base {
}
When to use Records?
DTOS, Immutable Objects,API response
\>> Records are a better choice than classes in situations where you are primarily storing data and not defining any behaviour.