รับอะไรเข้าทีมก่อน · เรียงตามสิ่งที่วัดได้
เจ็ดบทที่ผ่านมาวัดของใหม่ทีละอย่าง · บทนี้เอาผลมาเรียงเป็นลำดับ
และเกณฑ์ที่ใช้เรียงมีสองข้อเท่านั้น
เกณฑ์สองข้อ
หัวข้อที่มีชื่อว่า “เกณฑ์สองข้อ”ข้อแรกวัดสิ่งที่ได้ ข้อที่สองวัดความเสี่ยงตอนย้าย
ข้อแรก · ของนั้นบังคับความถูกต้องให้ตอนแปลหรือไม่
ของที่ทำให้ compiler จับความผิดพลาดแทนคนได้ คุ้มที่สุด เพราะมันได้ผลตลอดไป โดยไม่ต้องมีใครคอยระวัง
ข้อที่สอง · มันทำให้ของที่เคยทำงานอยู่พังได้หรือไม่
ของที่เปลี่ยนความหมายของ code เดิมเงียบๆ ต้องรับด้วยความระวัง ไม่ใช่ด้วยการกวาดทั้งโปรเจกต์
ลำดับที่ได้
หัวข้อที่มีชื่อว่า “ลำดับที่ได้”เรียงจากคุ้มที่สุดและปลอดภัยที่สุด ลงไปหาของที่ต้องคิดก่อน
| ลำดับ | ของ | บังคับตอนแปล | ทำของเดิมพังได้ |
|---|---|---|---|
| 1 | record | ใช่ | ไม่ |
| 2 | sealed + expression switch | ใช่ | ไม่ |
| 3 | record pattern | ใช่ | ได้ · เรื่อง null |
| 4 | Gatherers | ไม่ | ไม่ |
| 5 | virtual thread | ไม่ | ไม่ |
| 6 | StructuredTaskScope | ไม่ | ได้ · ยัง preview |
สามอันดับแรกได้ประโยชน์จากข้อแรกทั้งหมด · และมีเพียงอันดับที่ 3 ที่ติดข้อที่สอง
สามอันดับแรก ทำอย่างไร
หัวข้อที่มีชื่อว่า “สามอันดับแรก ทำอย่างไร”ไม่ใช่การกวาดทั้งโปรเจกต์ในสัปดาห์เดียว
record · ใช้กับของใหม่ทั้งหมด แล้วปล่อยของเก่าไว้
· ชนิดที่มีอยู่แล้วและทำงานถูกอยู่ ไม่ได้ผิดอะไร · ประโยชน์ของ record
อยู่ที่ชนิดที่ยังไม่ถูกเขียน
sealed + expression switch · เริ่มจากที่ที่มี switch เหนือ enum อยู่แล้ว
· บทที่ 3 แสดงว่ารูป statement เหนือ enum คือช่องเดียวที่ compiler ไม่บังคับ
· เปลี่ยนที่เหล่านั้นเป็น expression switch คือการย้ายจากช่องที่ไม่มีใครดู
ไปช่องที่มีคนดู โดยไม่ต้องเปลี่ยนโครงสร้างอะไรเลย
record pattern · ใช้กับ code ใหม่ ส่วน code เก่าให้ตรวจ null ก่อนย้าย
· นี่คืออันดับเดียวในสามอันดับแรกที่ทำของเดิมพังได้
switch ที่ครอบ sealed ครบ ถูกแปลโดยที่ compiler รับประกันว่าไม่มีทางตกกิ่ง
วันที่มีคนเพิ่มชนิดลูกเข้าไปแล้ว deploy เฉพาะฝั่งที่ประกาศชนิด โดยไม่ได้แปลฝั่งผู้เรียกใหม่ · ฝั่งผู้เรียกจะเจอค่าที่ไม่มีกิ่งไหนรับ แล้วโยน MatchExceptionMatchExceptionexception ที่ JVM โยนเมื่อไม่มีกิ่งไหนตรง ในรูปที่ compiler เคยรับประกันว่าครบ · มันโผล่เมื่อชนิดลูกถูกเพิ่มหลังจากที่ผู้เรียกถูกแปลไปแล้ว ออกมาตอนรัน
ข้อนี้ไม่ใช่ข้อเสียของ sealed · มันคือสิ่งที่ enum ก็เจอในรูปของมันเอง
แค่เงียบกว่า · แต่ถ้าทีมคุณ deploy ทีละส่วน ต้องรู้ว่าอะไรจะโผล่มา
flowchart TB
Q1{"บังคับความถูกต้องตอนแปลไหม"}
Q1 -->|"ใช่"| Q2{"ทำของเดิมพังได้ไหม"}
Q1 -->|"ไม่"| L["รับเมื่อมีงานที่มันแก้ได้จริง"]
Q2 -->|"ไม่"| A["รับได้เลย · record · sealed"]
Q2 -->|"ได้"| B["รับกับของใหม่ก่อน · record pattern"]
คำบรรยายภาพ: สองคำถาม กับสามคำตอบ ที่ใช้กับ feature ตัวไหนก็ได้
ของที่ไม่ได้อยู่ในลำดับ เพราะมันไม่ใช่การตัดสินใจ
หัวข้อที่มีชื่อว่า “ของที่ไม่ได้อยู่ในลำดับ เพราะมันไม่ใช่การตัดสินใจ”บางอย่างรับมาเลยได้โดยไม่ต้องคิด
- text block ไม่เปลี่ยนความหมายของอะไรเลย · ใช้ตรงที่มี string หลายบรรทัด
varเป็นเรื่องรสนิยม ไม่ใช่เรื่องความถูกต้อง- import moduleimport moduleการประกาศนำเข้าทั้งโมดูลในบรรทัดเดียว แทนการไล่นำเข้าทีละชนิด · ทำให้ตัวอย่างสั้นลงมาก แต่แลกกับการที่ผู้อ่านไม่เห็นว่าชนิดแต่ละตัวมาจากไหน ทำให้ตัวอย่างสั้นลงมาก แต่แลกกับการที่ผู้อ่านไม่เห็นว่า ชนิดแต่ละตัวมาจากไหน · เหมาะกับ script และตัวอย่างในเอกสาร มากกว่ากับ code ที่คนหลายคนต้องอ่าน
สิ่งที่คอร์สนี้ไม่ได้ทำ
หัวข้อที่มีชื่อว่า “สิ่งที่คอร์สนี้ไม่ได้ทำ”ปิดท้ายด้วยขอบเขต เพราะคอร์สที่ไม่บอกขอบเขต อ่านเหมือนคอร์สที่ตอบได้ทุกอย่าง
- ไม่มี build tool สักบท ทุกตัวอย่างแปลด้วย
javacและรันด้วยjava - ไม่แตะ framework เรื่องนั้นเป็นของ คอร์ส Kotlin กับ Spring Boot
- ไม่วัดความเร็ว ทั้งแปดบทไม่มีหน่วยเวลาสักตัว · หน่วยที่ใช้คือสถานะการแปล · ข้อความของ compiler · ชื่อและจำนวน member ใน bytecode · จำนวน thread · จำนวนครั้งที่ถูกเรียก
- ไม่พูดถึงของที่ยังไม่เข้ารุ่นไหน คอร์สนี้พูดถึงของที่แปลได้วันนี้เท่านั้น
คำถามที่ใช้กับ feature ตัวถัดไปที่ยังไม่ออก
หัวข้อที่มีชื่อว่า “คำถามที่ใช้กับ feature ตัวถัดไปที่ยังไม่ออก”ของที่เอากลับไปได้จริง ไม่ใช่รายการ feature แต่เป็นวิธีถาม
เมื่อ JDK รุ่นถัดไปออก และคุณเจอบทความที่บอกว่าของใหม่ดีอย่างไร ให้ถามสามข้อ
- มันอยู่สถานะไหนในรุ่นที่ผมรัน · ตอบด้วยการแปลสองรอบตามบทที่ 1 ไม่ใช่ด้วยการเชื่อบทความ
- มันบังคับอะไรให้ตอนแปล · ถ้าไม่บังคับอะไรเลย มันคือความสะดวก ไม่ใช่ความปลอดภัย
- มันทำให้ code ที่มีอยู่เปลี่ยนความหมายไหม · ตอบด้วยการรันของเก่ากับของใหม่
ด้วย input เดียวกัน รวมถึง
null
สามข้อนี้ไม่ผูกกับรุ่นไหน · และมันคือสิ่งที่คอร์สนี้ทำซ้ำแปดรอบ
จบคอร์ส
หัวข้อที่มีชื่อว่า “จบคอร์ส”แปดบท กับข้อสรุปที่ต่างจากที่หลายคนคาดไว้ตอนเริ่ม
คอร์สนี้เริ่มด้วยคำถามว่า ของพวกนี้ใช้ได้จริงแล้วหรือยัง และได้อะไรกลับมา
คำตอบที่ได้ไม่ใช่รายการ feature · มันคือนิสัยหนึ่งอย่าง คือ ถามเครื่องมือที่อยู่บนเครื่อง แทนการเชื่อข้อความที่เขียนไว้เมื่อสามปีก่อน
หลายข้อในคอร์สนี้กลับด้านไปจากที่ผมเขียนไว้ตอนแรก หลังจากรันแล้ว
· StructuredTaskScope ที่คิดว่านิ่งแล้ว ยังเป็น preview
· Gatherers กับ ScopedValue ที่คิดว่ายัง preview กลับ final แล้ว
· และ switch เหนือ enum ที่คิดว่าแดง กลับเขียวสนิทในรูปหนึ่ง
นั่นคือเหตุผลที่ทุกบทมีคำสั่งให้คุณรันเอง ไม่ใช่แค่ตัวเลขให้อ่าน
บทนี้ไม่ได้เพิ่มข้ออ้างใหม่ · มันเรียงผลของเจ็ดบทก่อนหน้า
- ทุกตัวเลขในคอร์สนี้รันซ้ำได้ด้วย
npm run verify:java-modern· วัดเมื่อ 2026-09-01 บนopenjdk 25.0.4.1 2026-08-18 - JEP 12 — Preview Features (เข้าถึง 2026-09-01) — สถานะและกติกาที่ใช้กับทุก feature ที่ยังไม่ final
- MatchException (เข้าถึง 2026-09-01) — กรณีที่ชนิดลูกถูกเพิ่มหลังจากผู้เรียกถูกแปลไปแล้ว
เช็กความเข้าใจ — บทที่ 8
ข้อ 1 / 3ในลำดับของบทนี้ ของอันดับที่ 3 คือ record pattern · มันต่างจากสองอันดับแรกตรงไหน