preview มีราคา และราคานั้นวัดได้
บทที่ 1 บอกว่ามีสอง feature ที่ยังเป็น preview ใน 25
บทนี้ตอบคำถามถัดไป · รับมาใช้แล้วจ่ายอะไร และคำตอบไม่ใช่ความรู้สึก
แปลด้วยธง แล้วรันโดยไม่ใส่ธง
หัวข้อที่มีชื่อว่า “แปลด้วยธง แล้วรันโดยไม่ใส่ธง”ทดลองสองบรรทัด แล้วอ่านสิ่งที่ JVM ตอบ
javac --release 25 --enable-preview -d out F.javajava -cp out FPreview features are not enabled for F (class file version 69.65535). Try running with '--enable-preview'บรรทัดเดียวจริงๆ · ยกมาทั้งบรรทัดโดยไม่ตัด เพราะเลขในวงเล็บคือส่วนที่สำคัญที่สุด
JVM ไม่ได้อ่าน code ของคุณแล้วตัดสินใจ · มันอ่านหัวของ class file แล้วปฏิเสธทันที
65535 คือเครื่องหมาย ไม่ใช่ตัวเลขบังเอิญ
หัวข้อที่มีชื่อว่า “65535 คือเครื่องหมาย ไม่ใช่ตัวเลขบังเอิญ”class file versionclass file versionเลขสองส่วนที่หัว class file บอกว่าแปลด้วยรุ่นไหน · ส่วนรองเป็น `65535` เมื่อ class นั้นถูกแปลด้วยธง preview ซึ่งเป็นสิ่งที่ JVM ใช้ปฏิเสธมัน มีสองส่วน · ส่วนหลักบอกรุ่น ส่วนรองบอกว่าเป็นของ preview
69 คือส่วนหลัก ซึ่งตรงกับ JDK 25 · 65535 คือส่วนรอง ซึ่งเป็นค่าสูงสุดที่ช่องนั้นเก็บได้
class file ธรรมดามีส่วนรองเป็น 0 · ส่วน class ที่แปลด้วยธง preview
ถูกประทับ 65535 ไว้ ถาวรในตัว file
ผลที่ตามมามีสามข้อ และทั้งสามข้อคือราคา
- class นั้นรันได้เฉพาะบน JDK รุ่นที่แปลมันเท่านั้น ไม่ใช่รุ่นนั้นขึ้นไป
- ต้องใส่ธงทุกที่ที่รัน ทั้งเครื่องพัฒนา ทั้ง CI ทั้งปลายทาง
- ของที่รวม class นั้นไว้ ติดข้อจำกัดเดียวกันทั้งก้อน
flowchart TB S["F.java"] -->|"javac --enable-preview"| C["F.class<br/>version 69.65535"] C -->|"java (ไม่ใส่ธง)"| X["ถูกปฏิเสธตั้งแต่อ่านหัว file"] C -->|"java --enable-preview"| OK["รันได้"] C -->|"JDK รุ่นอื่น"| X2["ถูกปฏิเสธ แม้ใส่ธง"]
คำบรรยายภาพ: ธงตอนแปลประทับเครื่องหมายลง class file แล้วเครื่องหมายนั้นตัดสินทุกอย่างหลังจากนั้น
ราคาข้อที่สองที่ไม่มีใครบอก · API เปลี่ยนรูปจริง
หัวข้อที่มีชื่อว่า “ราคาข้อที่สองที่ไม่มีใครบอก · API เปลี่ยนรูปจริง”บทที่ 1 แสดงไว้แล้ว แต่ตรงนี้คือที่ที่มันมีความหมาย
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { ... }รูปนี้เคยถูกต้องในรุ่นก่อนหน้า · วันนี้ได้ cannot find symbol
นี่คือสิ่งที่คำว่า preview หมายถึงจริงๆ · ไม่ใช่ “ยังไม่ค่อยเสถียร” แต่คือ “รูปของมันจะเปลี่ยน และของเก่าจะไม่มีทางเข้ากันได้”
ถ้าคุณเขียน code ด้วยรูปเก่าไว้หนึ่งพันบรรทัด การขึ้นรุ่นถัดไปคือการแก้ทั้งพันบรรทัดนั้น · ไม่ใช่การแก้ธงหนึ่งตัว
หนึ่ง · ของที่คุณกำลังสร้าง มีอายุยาวกว่ารอบการปล่อยของ JDK ไหม ถ้าเป็นเครื่องมือภายในที่ตายในหกเดือน ราคานี้แทบไม่มีความหมาย · ถ้าเป็น library ที่คนอื่นพึ่ง มันเป็นราคาที่คุณส่งต่อให้เขาด้วย
สอง · คุณคุมทุกที่ที่มันรันหรือเปล่า ถ้าคุมได้หมด การใส่ธงเป็นเรื่องของการตั้งค่าครั้งเดียว · ถ้ามีปลายทางที่คุณไม่คุม ข้อนี้ตอบว่าไม่ได้ทันที
สาม · มีทางอื่นที่ final แล้วไหม
StructuredTaskScope ทำสิ่งที่ ExecutorService ทำได้เกือบทั้งหมด แค่เขียนยาวกว่า
· ความยาวที่เพิ่มขึ้นคือราคาที่จ่ายครั้งเดียว ส่วน preview คือราคาที่จ่ายทุกรุ่น
ของที่หลายคนเลี่ยงโดยไม่จำเป็น
หัวข้อที่มีชื่อว่า “ของที่หลายคนเลี่ยงโดยไม่จำเป็น”ราคาข้างบนใช้กับ preview เท่านั้น · ไม่ได้ใช้กับของใหม่ทุกอย่าง
ScopedValueScopedValueค่าที่ส่งต่อลงไปในขอบเขตที่กำหนด โดยไม่ต้องส่งผ่าน argument ทุกชั้น · เข้ารุ่นถาวรแล้วใน JDK 25 ต่างจากที่หลายคนยังจำว่าเป็น preview เป็น final แล้วใน 25 · แต่มันเป็น preview มาหลายรุ่นติดกัน คนจึงจำภาพเก่าไว้
เหมือนกับ Gatherers ที่บทที่ 5 ใช้ · ทั้งคู่รันได้โดยไม่ต้องใส่ธงอะไรเลย
การเลี่ยงของที่ final แล้ว ไม่ได้ฟรี · คุณเขียนทางอ้อมที่ยาวกว่าโดยไม่ได้อะไรตอบแทน · และวิธีตรวจก็คือคำสั่งเดียวกับบทที่ 1 ซึ่งใช้เวลาน้อยกว่าการค้นหา
สิ่งที่บทนี้ยังไม่ทำ
หัวข้อที่มีชื่อว่า “สิ่งที่บทนี้ยังไม่ทำ”สองอย่างที่ยังไม่มี
- ไม่ได้บอกว่าควรรับหรือไม่รับ เพราะคำตอบขึ้นกับสามเกณฑ์ข้างบน ซึ่งเป็นข้อเท็จจริงของโปรเจกต์คุณ ไม่ใช่ของภาษา
- ไม่ได้แตะ incubator module ซึ่งเป็นสถานะที่ต่างจาก preview อีกชั้น และมีธงคนละตัว
สรุปก่อนไปต่อ
หัวข้อที่มีชื่อว่า “สรุปก่อนไปต่อ”บทนี้เปลี่ยนคำถามจาก “มันพร้อมหรือยัง” เป็น “ราคาของมันคืออะไร”
ราคาของ preview วัดได้สองอย่าง · เครื่องหมาย 65535 ที่ประทับลง class file
แล้วตัดสินทุกอย่างหลังจากนั้น และ รูปของ API ที่เปลี่ยนจริง
ทั้งสองข้อไม่ได้แปลว่าห้ามใช้ · มันแปลว่าให้ตัดสินใจโดยรู้ว่าจ่ายอะไร
บทหน้าเป็นบทสุดท้าย — เรารวมทุกอย่างที่วัดมาเป็นลำดับว่า ควรรับอะไรเข้าทีมก่อน
ข้อความที่ JVM ตอบ ยกมาทั้งบรรทัดจากการรันจริง:
- วัดเมื่อ 2026-09-01 ·
javac 25.0.4.1·openjdk 25.0.4.1 2026-08-18 - รันซ้ำเองได้ด้วย
npm run verify:java-modernซึ่งแปลด้วยธงแล้วรันสองรอบ · ช่องควบคุมคือรอบที่ใส่ธง ต้องรันผ่าน ถ้ามันไม่ผ่าน แปลว่าตัววัดพัง ไม่ใช่ข้ออ้างผิด - JEP 12 — Preview Features (เข้าถึง 2026-09-01) — กติกาของสถานะ preview และเหตุที่ class file ถูกตรึงกับรุ่น
- The Java Virtual Machine Specification
(เข้าถึง 2026-09-01) — ช่อง
minor_versionและค่า65535
เช็กความเข้าใจ — บทที่ 7
ข้อ 1 / 3class file ที่แปลด้วย `--enable-preview` มีเลขรุ่นส่วนรองเป็น `65535` · นั่นทำให้เกิดอะไร