ข้าม​ไป​ยัง​เนื้อหา

preview ไม่​ได้​ตรึง​แค่​ธง มัน​ตรึง class file ไว้​กับ​รุ่น

คำ​ว่า preview ใน Java ถูก​อ่าน​ว่า “ยัง​ไม่​ค่อย​เสถียร” กัน​เป็น​ส่วน​ใหญ่

ของ​จริง​เป็น​ข้อ​ที่​แข็ง​กว่า​นั้น​มาก และ​วัด​ได้​ด้วย​คำ​สั่ง​สอง​บรรทัด

Terminal window
javac --release 25 --enable-preview -d out F.java
java -cp out F
Preview features are not enabled for F (class file version 69.65535). Try running with '--enable-preview'

JVM ไม่​ได้​อ่าน code ของ​คุณ​แล้ว​ตัดสิน​ใจ · มัน​อ่าน​หัว​ของ class file แล้ว​ปฏิเสธ​ตั้งแต่​ตรง​นั้น

เลข​รุ่น​ของ class file มี​สอง​ส่วน · ส่วน​หลัก​บอก​รุ่น​ของ​ภาษา ส่วน​รอง​ปกติ​เป็น 0

69 ตรง​กับ JDK 25 · 65535 คือ​ค่า​สูงสุด​ที่​ช่อง​สอง​ไบต์​นั้น​เก็บ​ได้ · มัน​ถูก​เลือก​เพราะ​ไม่มี​ทาง​ชน​กับ​เลข​รุ่น​จริง​ใน​อนาคต

class ที่​แปล​ด้วย​ธง preview ถูก​ประทับ​เลข​นั้น​ไว้ ถาวร​ใน​ตัว file · ลบ​ไม่​ได้ แก้​ไม่​ได้ นอกจาก​แปล​ใหม่

  • class นั้น​รัน​ได้​เฉพาะ​บน JDK รุ่น​ที่​แปล​มัน​เท่านั้น · ไม่ใช่​รุ่น​นั้น​ขึ้น​ไป ซึ่ง​ต่าง​จาก class ธรรมดา​ที่​รุ่น​ใหม่​กว่า​รัน​ของ​เก่า​ได้
  • ต้อง​ใส่​ธง​ทุก​ที่​ที่​รัน ทั้ง​เครื่อง​พัฒนา ทั้ง CI ทั้ง​ปลาย​ทาง
  • ของ​ที่​รวม class นั้น​ไว้ ติด​ข้อ​จำกัด​เดียวกัน​ทั้ง​ก้อน · jar หนึ่ง​ใบ​ที่​มี class preview อยู่​หนึ่ง​ตัว กลาย​เป็น jar ที่​ผูก​กับ​รุ่น

คำ​ว่า preview ไม่​ได้​แปล​ว่า “อาจ​มี bug” · มัน​แปล​ว่า รูป​ของ​มัน​จะ​เปลี่ยน

try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { ... }

รูป​นี้​อยู่​ใน​บทความ​เรื่อง structured concurrency แทบ​ทุก​ชิ้น​ที่​เขียน​ระหว่าง​ปี 2023 ถึง 2025

แปล​บน JDK 25 แล้ว​ได้

error: cannot find symbol

ไม่ใช่​คำ​เตือน ไม่ใช่ deprecation · ชื่อ​นั้น​ไม่มี​อยู่​แล้ว

รูป​ที่​ใช้ได้​ใน​รุ่น​นี้​คือ

try (var scope = StructuredTaskScope.open()) {
var s = scope.fork(() -> 1);
scope.join();
System.out.println(s.get());
}
ถ้า​คุณ​เขียน​ด้วย​รูป​เก่า​ไว้​พัน​บรรทัด การ​ขึ้น​รุ่น​คือ​การ​แก้​พัน​บรรทัด​นั้น

ไม่ใช่​การ​แก้​ธง​หนึ่ง​ตัว · และ​ไม่มี​เครื่อง​มือ​ไหน​แปลง​ให้​อัตโนมัติ เพราะ​รูป​ที่​เปลี่ยน ไม่ใช่​แค่​ชื่อ แต่​เป็น​วิธี​ที่ scope รายงาน​ความ​ล้ม​เหลว

นี่​คือ​ความ​ต่าง​ระหว่าง “ยัง​ไม่​เสถียร” กับ “ยัง​ไม่​ตกลง​ว่า​จะ​มี​รูป​อย่างไร”

หนึ่ง · ของ​ที่​คุณ​สร้าง มีอายุ​ยาว​กว่า​รอบ​การ​ปล่อย​ของ JDK ไหม

เครื่อง​มือ​ภายใน​ที่​ตาย​ใน​หก​เดือน ราคา​นี้​แทบ​ไม่มี​ความ​หมาย · library ที่​คน​อื่น​พึ่ง เป็น​ราคา​ที่​คุณ​ส่ง​ต่อ​ให้​เขา​ด้วย

สอง · คุณ​คุม​ทุก​ที่​ที่​มัน​รัน​หรือ​เปล่า

ถ้า​มี​ปลาย​ทาง​ที่​คุณ​สั่ง​ให้​ใส่​ธง​ไม่​ได้ ข้อ​นี้​ตอบ​ว่า​ไม่​ได้​ทันที · ไม่​ต้อง​คิด​ต่อ

สาม · มี​ทาง​อื่น​ที่ final แล้ว​ไหม

ความ​ยาว​ที่​เพิ่ม​ขึ้น​จาก​การ​ใช้​ของ​เดิม คือ​ราคา​ที่​จ่าย​ครั้ง​เดียว · ส่วน preview คือ​ราคา​ที่​จ่าย​ทุก​รุ่น

ราคา​ข้าง​บน​ใช้​กับ preview เท่านั้น ไม่​ได้​ใช้​กับ​ของ​ใหม่​ทุก​อย่าง

วัด​บน JDK 25 ด้วย​การ​แปล​ตัวอย่าง​สอง​รอบ ต่าง​กัน​ที่​ธง​เดียว · ได้ แปด final สอง preview

finalpreview
record · sealed + switch · record pattern · text block · Gatherers · virtual thread · ScopedValue · import moduleStructuredTaskScope · ชนิด​พื้น​ฐาน​ใน pattern

Gatherers กับ ScopedValue เป็น preview มา​หลาย​รุ่น​ติด​กัน คน​จึง​จำ​ภาพ​เก่า​ไว้ · วัน​นี้​ทั้ง​คู่​รัน​ได้​โดย​ไม่​ต้อง​ใส่​ธง​อะไร​เลย

การ​เลี่ยง​ของ​ที่ final แล้ว ไม่​ได้​ฟรี · คุณ​เขียน​ทาง​อ้อม​ที่​ยาว​กว่า​โดย​ไม่​ได้​อะไร​ตอบแทน

Terminal window
javac --release 25 F.java # ผ่าน = final
javac --release 25 --enable-preview F.java # ผ่านเฉพาะรอบนี้ = preview

คำ​สั่ง​สอง​บรรทัด​นี้​ถาม compiler ที่​อยู่​บน​เครื่อง​คุณ ไม่​ได้​ถาม​คน​ที่​เขียน​เมื่อ​สาม​ปี​ก่อน · ใช้​กับ​รุ่น​ถัด​ไป​ที่​ยัง​ไม่​ออก​ได้​ด้วย


🔗 อ้างอิง​ต้นทาง

ทุก​ข้อความ​และ​ทุก​สถานะ​มา​จาก​การ​แปล​และ​รัน​จริง:

  • วัด​เมื่อ 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)
  • The Java Virtual Machine Specification (เข้า​ถึง 2026-09-01) — ช่อง minor_version และ​ค่า 65535
  • เรื่อง​นี้​เป็น​บท​ที่ 7 ของ คอร์ส Java 8 ถึง 25 ซึ่ง​วัด​ของ​อื่น​อีก​หก​อย่าง​ด้วย​หน่วย​เดียวกัน