0Pricing
Java Academy · บทเรียน

เริ่มต้นใช้งาน Records

ประกาศ records เป็นโครงสร้างเก็บข้อมูลแบบอ่านอย่างเดียวที่กระชับ และทำความเข้าใจสมาชิกที่สร้างขึ้นโดยอัตโนมัติ

เริ่มต้นใช้งาน Records เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

แนะนำเรคคอร์ด

เรคคอร์ดของ Java (Java 16 ขึ้นไป) เป็นวิธีประกาศคลาสบรรจุข้อมูลที่เปลี่ยนแปลงไม่ได้อย่างกระชับ โดยจะสร้างโค้ดซ้ำซ้อนให้โดยอัตโนมัติ ได้แก่ คอนสตรักเตอร์ เมธอดอ่านค่า equals, hashCode และ toString

การประกาศเรคคอร์ด

ใช้คีย์เวิร์ด record ตามด้วยชื่อเรคคอร์ดและรายการคอมโพเนนต์ คอมโพเนนต์แต่ละตัวจะกลายเป็นฟิลด์ส่วนตัวที่กำหนดค่าได้เพียงครั้งเดียว และมีเมธอดเข้าถึงแบบสาธารณะ

record Point(double x, double y) {}

Point p = new Point(3.0, 4.0);
System.out.println(p.x());      // 3.0 (accessor, not getX())
System.out.println(p.y());      // 4.0
System.out.println(p);          // Point[x=3.0, y=4.0]
System.out.println(p.equals(new Point(3.0, 4.0))); // true

สมาชิกที่สร้างโดยอัตโนมัติ

คอมไพเลอร์จะสร้างสิ่งต่อไปนี้ให้เรคคอร์ดทุกตัวโดยอัตโนมัติ: คอนสตรักเตอร์หลัก เมธอดเข้าถึงแบบสาธารณะ equals(), hashCode() และ toString() จึงไม่จำเป็นต้องเขียนสิ่งเหล่านี้เอง

record Product(String name, double price, int stock) {}

Product p1 = new Product("Widget", 9.99, 100);
Product p2 = new Product("Widget", 9.99, 100);

System.out.println(p1.name());          // Widget
System.out.println(p1.price());         // 9.99
System.out.println(p1.equals(p2));      // true (structural)
System.out.println(p1.hashCode() == p2.hashCode()); // true
System.out.println(p1);                 // Product[name=Widget, price=9.99, stock=100]

เรคคอร์ดเปลี่ยนแปลงไม่ได้

คอมโพเนนต์ของเรคคอร์ดเป็น final คุณไม่สามารถแก้ไขคอมโพเนนต์หลังการสร้างได้ เรคคอร์ดจึงเหมาะสำหรับจำลองออบเจ็กต์ค่าที่เปลี่ยนแปลงไม่ได้

record Money(long cents, String currency) {}

Money price = new Money(999, "USD");
// price.cents = 500; // Compile error — final field!

// To "update" a record, create a new one
Money discounted = new Money(price.cents() - 100, price.currency());
System.out.println(discounted); // Money[cents=899, currency=USD]

เรคคอร์ดสืบทอดจาก Object ได้เท่านั้น

เรคคอร์ดจะสืบทอดจาก java.lang.Record โดยปริยาย และไม่สามารถสืบทอดจากคลาสอื่นได้ แต่สามารถใช้งานอินเทอร์เฟซได้

interface Describable { String describe(); }

record Circle(double radius) implements Describable {
    public String describe() {
        return String.format("Circle with radius %.1f", radius);
    }

    public double area() {
        return Math.PI * radius * radius;
    }
}

Circle c = new Circle(5.0);
System.out.println(c.describe()); // Circle with radius 5.0
System.out.printf("Area: %.2f%n", c.area()); // Area: 78.54

เรคคอร์ดในคอลเลกชัน

เนื่องจากเรคคอร์ดใช้ equals และ hashCode อย่างถูกต้องโดยพิจารณาจากคอมโพเนนต์ทั้งหมด จึงสามารถใช้เป็นคีย์ของ Map และสมาชิกของ Set ได้อย่างถูกต้อง

import java.util.*;

record Coordinate(int row, int col) {}

Map<Coordinate, String> grid = new HashMap<>();
grid.put(new Coordinate(0, 0), "Origin");
grid.put(new Coordinate(1, 2), "Target");

// Lookup with equal-valued record works correctly
System.out.println(grid.get(new Coordinate(0, 0))); // Origin
System.out.println(grid.get(new Coordinate(1, 2))); // Target

Set<Coordinate> visited = new HashSet<>();
visited.add(new Coordinate(3, 3));
System.out.println(visited.contains(new Coordinate(3, 3))); // true

เรคคอร์ดในฐานะ DTO

เรคคอร์ดเหมาะอย่างยิ่งสำหรับออบเจ็กต์ถ่ายโอนข้อมูลใน API แบบ REST โดยใช้ส่งข้อมูลระหว่างเลเยอร์โดยไม่มีพฤติกรรมการทำงาน

record CreateUserRequest(String email, String displayName, String plan) {}

record UserResponse(long id, String email, String displayName,
                    String plan, String createdAt) {}

// Simulating a service call
static UserResponse createUser(CreateUserRequest req) {
    long id = 42L;
    return new UserResponse(id, req.email(), req.displayName(),
        req.plan(), java.time.Instant.now().toString());
}

CreateUserRequest req = new CreateUserRequest("alice@example.com", "Alice", "PRO");
UserResponse resp = createUser(req);
System.out.println(resp);

การแยกส่วนประกอบของเรคคอร์ด

เรคคอร์ดทำงานร่วมกับการจับคู่รูปแบบได้เป็นอย่างดี คุณสามารถแยกส่วนประกอบของเรคคอร์ดในนิพจน์สวิตช์ได้ (Java 21 ขึ้นไป)

sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
record Triangle(double base, double height) implements Shape {}

static double area(Shape s) {
    return switch (s) {
        case Circle(double r)            -> Math.PI * r * r;
        case Rectangle(double w, double h) -> w * h;
        case Triangle(double b, double h) -> 0.5 * b * h;
    };
}

System.out.printf("%.2f%n", area(new Circle(5)));         // 78.54
System.out.printf("%.2f%n", area(new Rectangle(4, 6)));   // 24.00

การทำซีเรียลไลซ์เรคคอร์ด

เรคคอร์ดสามารถใช้งาน Serializable ได้โดยธรรมชาติเมื่อประกาศให้รองรับ เรคคอร์ดทำงานร่วมกับไลบรารี JSON เช่น Jackson และ Gson ได้ทันที

// With Jackson (add @JsonProperty if needed)
import com.fasterxml.jackson.databind.ObjectMapper;

record OrderSummary(String orderId, double total, String status) {}

ObjectMapper mapper = new ObjectMapper();
OrderSummary order = new OrderSummary("ORD-001", 149.99, "SHIPPED");

String json = mapper.writeValueAsString(order);
System.out.println(json);
// {"orderId":"ORD-001","total":149.99,"status":"SHIPPED"}

OrderSummary restored = mapper.readValue(json, OrderSummary.class);
System.out.println(order.equals(restored)); // true

เรคคอร์ดซ้อนกัน

เรคคอร์ดสามารถมีเรคคอร์ดอื่นเป็นคอมโพเนนต์ได้ ทำให้สร้างกราฟออบเจ็กต์ที่เปลี่ยนแปลงไม่ได้และมีโครงสร้างสมบูรณ์

record Address(String street, String city, String country) {}
record Customer(long id, String name, Address address) {}

Address addr = new Address("123 Main St", "New York", "US");
Customer customer = new Customer(1L, "Alice", addr);

System.out.println(customer.name());              // Alice
System.out.println(customer.address().city());   // New York
System.out.println(customer);                    // Customer[id=1, name=Alice, address=Address[street=123 Main St, city=New York, country=US]]

ข้อจำกัดของเรคคอร์ด

เรคคอร์ดมีข้อจำกัดบางประการที่ควรทราบ:

  • ไม่สามารถสืบทอดจากคลาสอื่นได้ (โดยปริยายจะสืบทอดจาก Record)
  • คอมโพเนนต์เป็น final เสมอ จึงไม่มีสถานะที่เปลี่ยนแปลงได้
  • ไม่สามารถประกาศฟิลด์อินสแตนซ์นอกเหนือจากรายการคอมโพเนนต์ได้
  • ไม่สามารถเป็นคลาสนามธรรมได้
// Records CAN have static fields and methods
record Temperature(double celsius) {
    static final double ABSOLUTE_ZERO = -273.15;

    public double toFahrenheit() {
        return celsius * 9.0/5.0 + 32;
    }

    public static Temperature fromFahrenheit(double f) {
        return new Temperature((f - 32) * 5.0/9.0);
    }
}
System.out.println(Temperature.fromFahrenheit(98.6)); // Temperature[celsius=37.0]

ตรวจสอบความเข้าใจ

คอมไพเลอร์ Java จะสร้างสมาชิกใดให้เรคคอร์ดโดยอัตโนมัติ

สรุปทบทวน: แนะนำเรคคอร์ด

ประเด็นสำคัญ:

  • เรคคอร์ดใช้ประกาศออบเจ็กต์บรรจุข้อมูลที่เปลี่ยนแปลงไม่ได้ โดยมีโค้ดซ้ำซ้อนน้อยที่สุด
  • สิ่งที่สร้างโดยอัตโนมัติ ได้แก่ คอนสตรักเตอร์หลัก เมธอดเข้าถึง equals, hashCode และ toString
  • คอมโพเนนต์เป็น final เรคคอร์ดจึงเปลี่ยนแปลงไม่ได้ตั้งแต่การออกแบบ
  • เรคคอร์ดสามารถใช้งานอินเทอร์เฟซได้ แต่ไม่สามารถสืบทอดจากคลาสได้
  • เหมาะอย่างยิ่งสำหรับ DTO ออบเจ็กต์ค่า และการตอบกลับจาก API
  • สามารถใช้เป็นคีย์ของ HashMap และสมาชิกของ HashSet ได้อย่างถูกต้อง เนื่องจากเปรียบเทียบความเท่ากันตามโครงสร้าง

คำถามที่พบบ่อย

บทเรียน “เริ่มต้นใช้งาน Records” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “เริ่มต้นใช้งาน Records” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “เริ่มต้นใช้งาน Records”

ประกาศ records เป็นโครงสร้างเก็บข้อมูลแบบอ่านอย่างเดียวที่กระชับ และทำความเข้าใจสมาชิกที่สร้างขึ้นโดยอัตโนมัติ คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “เริ่มต้นใช้งาน Records” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เริ่มต้นใช้งาน Records
  2. ตัวสร้างแบบกระชับและการตรวจสอบความถูกต้อง
  3. เมธอดแบบกำหนดเองบน Records
  4. Records กับคลาสและ Lombok
← กลับไปที่ Java Academy