ตัวสร้างแบบกระชับและการตรวจสอบความถูกต้อง
เพิ่มตรรกะตรวจสอบความถูกต้องภายในตัวสร้างแบบกระชับ เพื่อรับรองความสมบูรณ์ของข้อมูล
ตัวสร้างแบบกระชับและการตรวจสอบความถูกต้อง เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คอนสตรักเตอร์แบบย่อ
คอนสตรักเตอร์แบบย่อในเรคคอร์ดจะทำงานก่อนกำหนดค่าคอมโพเนนต์ ช่วยให้คุณตรวจสอบหรือปรับรูปแบบข้อมูลได้โดยไม่ต้องเขียนคำสั่งกำหนดค่าคอมโพเนนต์ซ้ำ
คอนสตรักเตอร์มาตรฐานเทียบกับคอนสตรักเตอร์แบบย่อ
คอนสตรักเตอร์หลักแบบมาตรฐานจะกำหนดค่าคอมโพเนนต์อย่างชัดเจน ส่วนคอนสตรักเตอร์แบบย่อจะไม่ระบุรายการพารามิเตอร์และคำสั่งกำหนดค่า เพราะระบบจะดำเนินการให้อัตโนมัติหลังจากบอดีทำงานเสร็จ
// Standard canonical constructor
record Range(int min, int max) {
Range(int min, int max) {
if (min > max) throw new IllegalArgumentException("min > max");
this.min = min; // explicit assignment
this.max = max;
}
}
// Compact constructor (same behavior, less code)
record Range2(int min, int max) {
Range2 { // no parameter list, no assignments
if (min > max) throw new IllegalArgumentException("min > max");
// components are assigned automatically after this block
}
}การตรวจสอบข้อมูลในคอนสตรักเตอร์แบบย่อ
คอนสตรักเตอร์แบบย่อเป็นวิธีมาตรฐานสำหรับตรวจสอบข้อมูลของเรคคอร์ด ควรโยนข้อยกเว้นตั้งแต่เนิ่น ๆ เพื่อบังคับใช้เงื่อนไขคงที่ของข้อมูล
record Email(String address) {
Email {
if (address == null || address.isBlank())
throw new IllegalArgumentException("Email cannot be blank");
if (!address.contains("@"))
throw new IllegalArgumentException("Invalid email: " + address);
address = address.toLowerCase().strip(); // normalize (Java 16+)
}
}
Email e = new Email(" Alice@Example.com ");
System.out.println(e.address()); // alice@example.com
try { new Email("not-an-email"); }
catch (IllegalArgumentException ex) { System.out.println(ex.getMessage()); }การปรับรูปแบบข้อมูลในคอนสตรักเตอร์แบบย่อ
คุณสามารถแก้ไขตัวแปรคอมโพเนนต์ภายในคอนสตรักเตอร์แบบย่อ ก่อนที่ตัวแปรเหล่านั้นจะได้รับการกำหนดค่า วิธีนี้ช่วยปรับรูปแบบข้อมูลขณะสร้างออบเจ็กต์
record PersonName(String firstName, String lastName) {
PersonName {
firstName = capitalize(firstName);
lastName = capitalize(lastName);
}
private static String capitalize(String s) {
if (s == null || s.isEmpty()) return s;
return Character.toUpperCase(s.charAt(0)) +
s.substring(1).toLowerCase();
}
public String fullName() { return firstName + " " + lastName; }
}
PersonName name = new PersonName("jOHN", "DOE");
System.out.println(name.fullName()); // John Doeการคัดลอกเพื่อป้องกัน
สำหรับคอมโพเนนต์ที่เปลี่ยนแปลงได้ เช่น อาร์เรย์หรือคอลเลกชัน ให้คัดลอกข้อมูลเพื่อป้องกันภายในคอนสตรักเตอร์แบบย่อ เพื่อรักษาคุณสมบัติการเปลี่ยนแปลงไม่ได้
import java.util.*;
record Snapshot(List<String> items) {
Snapshot {
items = List.copyOf(items); // defensive copy — unmodifiable
}
}
List<String> mutable = new ArrayList<>(List.of("a", "b", "c"));
Snapshot snap = new Snapshot(mutable);
mutable.add("d"); // doesn't affect snapshot
System.out.println(snap.items()); // [a, b, c]
try {
snap.items().add("e"); // UnsupportedOperationException
} catch (UnsupportedOperationException e) {
System.out.println("Snapshot is truly immutable!");
}เรคคอร์ด Range พร้อมขอบเขต
เรคคอร์ด Range ภาคปฏิบัติที่รับประกันว่า min <= max และมีเมธอดยูทิลิตีที่เป็นประโยชน์
record Range(int min, int max) {
Range {
if (min > max) throw new IllegalArgumentException(
"min (" + min + ") must be <= max (" + max + ")");
}
public boolean contains(int value) { return value >= min && value <= max; }
public int size() { return max - min; }
public int clamp(int value) { return Math.max(min, Math.min(max, value)); }
}
Range valid = new Range(1, 10);
System.out.println(valid.contains(5)); // true
System.out.println(valid.clamp(15)); // 10
System.out.println(valid.size()); // 9การเรียกต่อเนื่องของตรรกะในคอนสตรักเตอร์แบบย่อ
สำหรับการตรวจสอบที่ซับซ้อน ให้แยกเมธอดช่วยเหลือออกมา แล้วเรียกใช้จากคอนสตรักเตอร์แบบย่อ
record CreditCard(String number, String cvv, int expiryMonth, int expiryYear) {
CreditCard {
validateNumber(number);
validateCvv(cvv);
validateExpiry(expiryMonth, expiryYear);
number = number.replaceAll("[^0-9]", ""); // strip spaces/dashes
}
private static void validateNumber(String n) {
String digits = n.replaceAll("[^0-9]", "");
if (digits.length() < 13 || digits.length() > 19)
throw new IllegalArgumentException("Invalid card number length");
}
private static void validateCvv(String cvv) {
if (!cvv.matches("[0-9]{3,4}"))
throw new IllegalArgumentException("Invalid CVV");
}
private static void validateExpiry(int m, int y) {
if (m < 1 || m > 12) throw new IllegalArgumentException("Invalid month");
if (y < 2024) throw new IllegalArgumentException("Card expired");
}
}รูปแบบคอนสตรักเตอร์แบบย่อหลายรูปแบบ
รูปแบบการตรวจสอบที่ใช้กันทั่วไปในคอนสตรักเตอร์แบบย่อ
record Percentage(double value) {
Percentage {
if (value < 0 || value > 100)
throw new IllegalArgumentException(
"Percentage must be 0-100, got: " + value);
value = Math.round(value * 100.0) / 100.0; // round to 2 dp
}
public double asFraction() { return value / 100.0; }
}
Percentage tax = new Percentage(8.756);
System.out.println(tax.value()); // 8.76
System.out.println(tax.asFraction()); // 0.0876คอนสตรักเตอร์ที่ไม่ใช่แบบหลัก
เรคคอร์ดสามารถมีคอนสตรักเตอร์เพิ่มเติมได้ แต่คอนสตรักเตอร์เหล่านั้นต้องส่งต่อไปยังคอนสตรักเตอร์หลักโดยใช้ this(...)
record Point(double x, double y) {
// Non-canonical constructor: origin point
Point() { this(0.0, 0.0); }
// Non-canonical: polar coordinates
static Point fromPolar(double r, double theta) {
return new Point(r * Math.cos(theta), r * Math.sin(theta));
}
public double distance(Point other) {
double dx = this.x - other.x;
double dy = this.y - other.y;
return Math.sqrt(dx*dx + dy*dy);
}
}
Point origin = new Point();
Point p = Point.fromPolar(5, Math.PI/4);
System.out.printf("Distance: %.2f%n", origin.distance(p)); // 5.00เรคคอร์ดคอลเลกชันที่เปลี่ยนแปลงไม่ได้
เรคคอร์ดที่เก็บสแนปชอตที่เปลี่ยนแปลงไม่ได้ของการตั้งค่าผู้ใช้ และตรวจสอบพร้อมปรับรูปแบบข้อมูลขณะสร้าง
import java.util.*;
record UserPreferences(String theme, Set<String> enabledFeatures, int fontSize) {
private static final Set<String> VALID_THEMES = Set.of("light", "dark", "system");
private static final Set<String> VALID_FEATURES = Set.of("ai", "beta", "analytics");
UserPreferences {
if (!VALID_THEMES.contains(theme))
throw new IllegalArgumentException("Unknown theme: " + theme);
if (!VALID_FEATURES.containsAll(enabledFeatures))
throw new IllegalArgumentException("Unknown feature in: " + enabledFeatures);
if (fontSize < 10 || fontSize > 24)
throw new IllegalArgumentException("fontSize must be 10-24");
enabledFeatures = Set.copyOf(enabledFeatures); // defensive copy
}
}ข้อจำกัดของคอนสตรักเตอร์แบบย่อ
สิ่งที่คุณไม่สามารถทำได้ในคอนสตรักเตอร์แบบย่อ:
- ไม่สามารถกำหนดค่าคอมโพเนนต์อย่างชัดเจนได้ (ระบบจะกำหนดค่าให้อัตโนมัติหลังจบบล็อก)
- ไม่สามารถเรียก
this()หรือsuper()ได้ - การโยนข้อยกเว้นจะป้องกันไม่ให้กำหนดค่าคอมโพเนนต์ใด ๆ
record Safe(int value) {
Safe {
// CAN: validate and modify component variables
if (value < 0) value = 0; // normalized to 0 if negative
// value = this.value; // NOT NEEDED — assignment happens after block
}
}
System.out.println(new Safe(-5).value()); // 0 (normalized)
System.out.println(new Safe(10).value()); // 10ตรวจสอบความเข้าใจ
ในคอนสตรักเตอร์แบบย่อ การแก้ไขตัวแปรคอมโพเนนต์ที่คุณทำจะส่งผลอย่างไร
สรุปทบทวน: คอนสตรักเตอร์แบบย่อและการตรวจสอบข้อมูล
ประเด็นสำคัญ:
- คอนสตรักเตอร์แบบย่อทำงานก่อนกำหนดค่าคอมโพเนนต์ จึงไม่ต้องกำหนดค่าอย่างชัดเจน
- ใช้สำหรับตรวจสอบ ปรับรูปแบบ หรือคัดลอกคอมโพเนนต์เพื่อป้องกัน
- แก้ไขตัวแปรคอมโพเนนต์เพื่อปรับรูปแบบค่า เช่น เปลี่ยนเป็นตัวพิมพ์เล็ก ตัดช่องว่าง หรือคัดลอก
- โยน IllegalArgumentException สำหรับข้อมูลที่ไม่ถูกต้อง เพื่อบังคับใช้เงื่อนไขคงที่
- ใช้ List.copyOf / Set.copyOf สำหรับคอมโพเนนต์คอลเลกชันที่เปลี่ยนแปลงได้
- คอนสตรักเตอร์ที่ไม่ใช่แบบหลักต้องส่งต่อไปยังคอนสตรักเตอร์หลักด้วย this(...)
คำถามที่พบบ่อย
บทเรียน “ตัวสร้างแบบกระชับและการตรวจสอบความถูกต้อง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตัวสร้างแบบกระชับและการตรวจสอบความถูกต้อง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตัวสร้างแบบกระชับและการตรวจสอบความถูกต้อง”
เพิ่มตรรกะตรวจสอบความถูกต้องภายในตัวสร้างแบบกระชับ เพื่อรับรองความสมบูรณ์ของข้อมูล คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “ตัวสร้างแบบกระชับและการตรวจสอบความถูกต้อง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เริ่มต้นใช้งาน Records
- ตัวสร้างแบบกระชับและการตรวจสอบความถูกต้อง
- เมธอดแบบกำหนดเองบน Records
- Records กับคลาสและ Lombok