DEV Community

Abhishek Singh
Abhishek Singh

Posted on

Java Records

All About Java Records :

Overview :
Java Records, introduced in Java 14 as a preview feature and finalized in Java 16, provides a concise way to model immutable data. They simplify the boilerplate code needed for data-carrying classes by automatically generating methods like equals(), hashCode() and toString()

By the end of this post we will understand:

What records are in Java?
How to create and use records in Java?
The benefits of using records in Java?
And some limitations of records in Java?

What are Records?
A record in Java is a special kind of class that is designed to hold immutable data. It automatically provides implementations for methods like:

equals()
hashCode()
toString()
Getters for all fields

Why Use Records?
Records help reduce boilerplate code in data classes. Instead of writing constructors, getters, equals(), hashCode(), and toString() methods manually, we can define all of this with a single line of code

How to Define a Record?
Here's how we can define a simple record:

public record Point(int x, int y) {
}

Enter fullscreen mode Exit fullscreen mode

This single line of code automatically provides:

  1. A constructor
  2. Getters (x() and y())
  3. equals(), hashCode(), and toString() methods

Example: How to use Records?
Let's see how we can use the Point record:

public class Main {
    public static void main(String[] args) {
        Point point = new Point(3, 4);

        // Using the auto-generated toString() method
        System.out.println(point);  // Output: Point[x=3, y=4]

        // Accessing the fields using auto-generated methods
        System.out.println("X: " + point.x());  // Output: X: 3
        System.out.println("Y: " + point.y());  // Output: Y: 4
    }
}
Enter fullscreen mode Exit fullscreen mode

Example: Custom Methods in Records :
You can also add custom methods to records:

public record Point(int x, int y) {
    public double distanceFromOrigin() {
        return Math.sqrt(x * x + y * y);
    }
}

public class Main {
    public static void main(String[] args) {
        Point point = new Point(3, 4);
        System.out.println("Distance from origin: " + point.distanceFromOrigin());  // Output: 5.0
    }
}
Enter fullscreen mode Exit fullscreen mode

Custom Constructors :
We can also define custom constructors in records, but they must delegate to the canonical constructor:

public record Point(int x, int y) {
    public Point(int x) {
        this(x, 0);  // Delegating to the canonical constructor
    }
}
Enter fullscreen mode Exit fullscreen mode

Limitations of Records :

1. Immutability: Records are immutable by design. You cannot change the values of their fields after creation.

2. No Inheritance: Records cannot extend other classes. They implicitly extend java.lang.Record

3. All-Args Constructor: We cannot create a no-argument constructor directly in records. We must always provide all the components.

When to Use Records :
Use records when:

  1. We need a simple, immutable data carrier class

  2. We want to reduce boilerplate code for equals(), hashCode(), and toString() methods

  3. We don't need to extend another class or implement complex behavior

Practical Example :
Let's create a more complex example with a Person record:

public record Person(String name, int age) {
    public Person {
        // Custom constructor with validation
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative");
        }
    }

    // Custom method
    public String greeting() {
        return "Hello, my name is " + name + " and I am " + age + " years old.";
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);
        System.out.println(person.greeting());  // Output: Hello, my name is Alice and I am 30 years old.
        System.out.println(person);  // Output: Person[name=Alice, age=30]
    }
}

Enter fullscreen mode Exit fullscreen mode

Key Points :

  1. Definition:
    public record Person(String name, int age) {}

  2. Custom Constructor:
    Validates that age is non-negative

  3. Custom Method:
    Adds a greeting() method

Conclusion :
Java Records provide a simple and powerful way to create immutable data classes with minimal boilerplate code. They are especially useful for modeling data transfer objects and other simple data carriers. By understanding and using records, you can write cleaner and more concise code.

Happy Coding...

Top comments (0)