Java Records: Immutable Data Classes (Java 16+)
#java13 เม.ย. 2569
Records คืออะไร
Records (Java 16+) เป็น special class สำหรับ immutable data ที่ Java สร้าง constructor, getters, equals, hashCode, toString ให้อัตโนมัติ
สร้าง Record
// แทนที่ class ยาวๆ
public record Point(int x, int y) {}
// ใช้งาน
Point p = new Point(3, 4);
System.out.println(p.x()); // 3
System.out.println(p.y()); // 4
System.out.println(p); // Point[x=3, y=4]
Point p2 = new Point(3, 4);
System.out.println(p.equals(p2)); // true
Record กับ Validation
public record Person(String name, int age) {
// Compact constructor
public Person {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("ชื่อต้องไม่ว่าง");
}
if (age < 0 || age > 150) {
throw new IllegalArgumentException("อายุไม่ถูกต้อง");
}
name = name.trim(); // normalize
}
}
Person p = new Person(" สมชาย ", 25);
System.out.println(p.name()); // "สมชาย" (trimmed)
Record กับ Methods
public record Money(double amount, String currency) {
// Custom method
public Money add(Money other) {
if (!this.currency.equals(other.currency)) {
throw new IllegalArgumentException("สกุลเงินไม่ตรงกัน");
}
return new Money(this.amount + other.amount, this.currency);
}
public Money multiply(double factor) {
return new Money(this.amount * factor, this.currency);
}
public boolean isPositive() {
return amount > 0;
}
}
Money price = new Money(100.0, "THB");
Money tax = new Money(7.0, "THB");
Money total = price.add(tax);
System.out.println(total); // Money[amount=107.0, currency=THB]
Record กับ Interface
public interface Describable {
String describe();
}
public record Product(String name, double price) implements Describable {
@Override
public String describe() {
return name + " ราคา " + price + " บาท";
}
}
Generic Record
public record Pair<A, B>(A first, B second) {
public Pair<B, A> swap() {
return new Pair<>(second, first);
}
}
Pair<String, Integer> pair = new Pair<>("hello", 42);
Pair<Integer, String> swapped = pair.swap();
เปรียบเทียบกับ Class เดิม
// ก่อน Records - ~50 บรรทัด
public class PersonOld {
private final String name;
private final int age;
// constructor, getters, equals, hashCode, toString...
}
// หลัง Records - 1 บรรทัด
public record Person(String name, int age) {}
สรุป
Records ลด boilerplate code ได้มากสำหรับ data classes เหมาะกับ DTOs, Value Objects, API responses ที่ต้องการ immutability ครับ