INTRODUCTION
We are learning one of good feature of java which record class. What is record class and when to use record class in your application. How record helps developer to remove boilerplate code from the application.
What is Record ?
A record class is introduced in java when we need immutable data. This class act like a data carrier i.e. model or POJO class. The Java compiler auto generates getter methods, toString(), hashcode() and equals() methods for these data fields, so you don't have to write that boilerplate code yourself. Since a Java Record is immutable, no setter methods are generated. There are 3 characteristics of record class
- Immutability
- Automatic methods like getter, toString() , hashcode() and equals().
- Transparent field access.
Why do we need record ?
Whenever you write java class , you need to add boilerplate code in java class like
- Getter and Setter method for fields.
- Need to override equals() and hashcode() methods.
- Need to write constructor.
- Need to write toString() methods.
So lets create a class, and add above boilerplate code in it.
Example :
public class Employee {
private String name;
private String salary;
private String bloodGroup;
public Employee(String name, String salary, String bloodGroup) {
this.name = name;
this.salary = salary;
this.bloodGroup = bloodGroup;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getBloodGroup() {
return bloodGroup;
}
public void setBloodGroup(String bloodGroup) {
this.bloodGroup = bloodGroup;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", salary='" + salary + '\'' +
", bloodGroup='" + bloodGroup + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return Objects.equals(name, employee.name) && Objects.equals(salary, employee.salary) && Objects.equals(bloodGroup, employee.bloodGroup);
}
@Override
public int hashCode() {
return Objects.hash(name, salary, bloodGroup);
}
}
Also sometimes we can use some annotations to avoid boilerplate code.
Example :
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class Employee {
private String name;
private String salary;
private String bloodGroup;
}
So It is good to works with annotation when this Java feature is not there, So We can use record class to avoid boilerplate code and code with annotations. We can do above code in one liner code.
Hence Record class comes in picture.
Record Syntax :
public record Employee(String name , String salary , String bloodGroup) {
}
So when we create object of employee class, it looks like below:
Example :
public class Company {
public static void main (String[] args) {
Employee employee = new Employee("Ashish" , "50000", "O+");
System.out.println(employee.name());
System.out.println(employee.salary());
System.out.println(employee);
}
}
In the above example, when we create Employee record, the compiler creates bytes code and includes the following in the generated class file.
- Getter method for fields.
- equals() and hashcode() method.
- default constructor.
- toString() method.
- The class is marked as final so we can not inherit the class.
- All the data are immutable as no setter method is provided.
Additional Features of Record class :
1) Canonical Constructor :
JVM provide all argument constructor by default it is called as Canonical constructor. We can override this constructor and add our custom logic like data validation.
Example :
public record Employee(String name, String salary, String bloodGroup) {
private String name;
private String salary;
private String bloodGroup;
public Employee(String name, String salary, String bloodGroup) {
if (name == null) {
throw new IllegalArgumentException("name should not be null");
}
if(salary < 5000) {
throw new IllegalArgumentException("salary should be greater than 5000");
}
}
}
So Writing canonical constructor is boilerplate code , thus we can use compact constructor.
2) Compact Constructor :
In Compact constructor , we just remove the argument parathesis of constructor.
Example :
public record Employee(String name, String salary, String bloodGroup) implements Serializable{
private String name;
private String salary;
private String bloodGroup;
public Employee{
if (name == null) {
throw new IllegalArgumentException("name should not be null");
}
if(salary < 5000) {
throw new IllegalArgumentException("salary should be greater than 5000");
}
}
}
3) Instance Methods in record :
Just like java class , we can add methods in record class.
Example :
public record Employee(String name, String salary, String bloodGroup) {
public String toNameLowercase() {
return name.toLowerCase();
}
public String toNameUppercase() {
return name.toUpperCase();
}
}
4) Static methods in record class :
Just like java class, we can add static methods in record class.
Example :
public record Employee(String name, String salary, String bloodGroup) {
public static final String UNKNOWN_BLOOD_GROUP = "unknow bloodgroup";
public static String unknowBloodGroup() {
return UNKNOWN_BLOOD_GROUP;
}
}
SUMMARY
So using record class, how we can avoided boilerplate code from java class. Also how it helps to maintain immutability of data. Records can be extended by additional constructors, static fields, and static as well as non-static methods. The canonical constructor can be overridden. Records can implement interface but can not extend class.
0 Comments
Post a Comment