avatarUğur Taş

Summary

The article discusses methods for implementing data validation and normalization within Java record classes, enhancing their functionality beyond simple data transfer objects.

Abstract

Java record classes simplify the creation of data transfer objects by reducing boilerplate code, but they lack built-in mechanisms for data validation and normalization. The article explains how developers can leverage record classes by manually writing constructors that include parameter validation and field normalization. It provides an example of a User record class with a custom constructor that ensures non-empty names and standardizes email addresses to lowercase. The author emphasizes the importance of these enhancements for maintaining data integrity and suggests that these practices improve code readability and maintainability, which is beneficial for all Java developers.

Opinions

  • The author believes that Java record classes significantly contribute to code readability and maintainability.
  • It is implied that every Java developer would recognize the benefits of record classes.
  • The article suggests that the ability to manipulate constructors in record classes is a valuable feature for data validation and normalization.
  • The author shows a clear preference for non-empty names and lowercase email addresses as examples of good data hygiene practices.
  • There is an underlying assumption that developers should take advantage of the features provided by record classes to enhance their applications' data integrity.
  • The author values community engagement and encourages readers to share their feedback to help improve the content's value.

How to Validate and Normalize Data For Java Record Classes?

If you don’t have a medium membership, you can use this link to reach the article without a paywall.

First things first, if you are interested in record class topics, don’t forget to take a look at my other record class-related posts 👇

Java record class type made data transfer object creation easy. It allows us to reduce boilerplate code from our codebase. Almost only one line of code handles what we did with hundreds of lines of code before. The record classes added a lot to the readability of the code in Java, and I believe every Java developer agrees.

For example, this one line of record class:

record User(String name, int age, String email) {}

is equal to this traditional Java class:

public final class User {
  public final String name;
  public final int age;
  public final String email;

  public User(String name, int age, String email) {
    this.name = name;
    this.age = age;
    this.email = email;
  }

  public String getName() {
    return name;
  }

  public int getAge() {
    return age;
  }

  public String getEmail() {
    return email;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {return true;}
    if (o == null || getClass() != o.getClass()) {return false;}
    User user = (User) o;
    return age == user.age && Objects.equals(name, user.name) && Objects.equals(email, user.email);
  }

  @Override
  public int hashCode() {
    return Objects.hash(name, age, email);
  }

  @Override
  public String toString() {
    return "User{" +
        "name='" + name + '\'' +
        ", age=" + age +
        ", email='" + email + '\'' +
        '}';
  }
}

The example shows how it is convenient when dealing with data objects. But with traditional classes, we could validate the parameters or normalize them.

How validation and normalization can be handled in record classes? I will try to answer this question.

Records give us a chance to manipulate the constructor method. We can validate parameters before setting fields and even change them by rewriting the constructor.

As an example, we have seen how the User record class is implemented. It is handy to use, but what if we would like to have non-empty names and always lowercase email addresses. This is not possible with the current implementation, however, we can enhance it.

public record User(String name, int age, String email) {

  public User(String name, int age, String email) {
    if(name == null || name.isBlank()) {
      throw new IllegalArgumentException("error message");
    }

    this.name = name.trim();
    this.age = age;
    this.email = email.toLowerCase(Locale.ROOT);
  }
}

By writing our own constructor, we can handle null checks for the name field, trimming for the name field, and setting the email field value to lowercase. We can validate the email field with the email pattern by using the same approach.

I hope you understand how to enhance your Java record classes with validations.

👏 Thank You for Reading!

👨‍💼 I appreciate your time and hope you found this story insightful. If you enjoyed it, don’t forget to show your appreciation by clapping 👏 for the hard work!

📰 Keep the Knowledge Flowing by Sharing the Article!

✍ Feel free to share your feedback or opinions about the story. Your input helps me improve and create more valuable content for you.

✌ Stay Connected! 🚀 For more engaging articles, make sure to follow me on social media:

🔍 Explore More! 📖 Dive into a treasure trove of knowledge at Codimis. There’s always more to learn, and we’re here to help you on your journey of discovery.

Java
Java Records
Validation
Normalization
Constructor
Constructor Function
Recommended from ReadMedium