ประเภทแบบจำกัด null และประเภทที่ยอมรับ null
(bugs.openjdk.org)Null-Restricted and Nullable Types (Preview)
สรุป
ฟีเจอร์ภาษารุ่นพรีวิวที่รองรับตัวทำเครื่องหมาย nullness ซึ่งใช้ระบุว่าประเภทใน Java ยอมรับหรือปฏิเสธ null ได้
เป้าหมาย
- ปรับปรุงประเภทอ้างอิงของ Java เพื่อให้โปรแกรมเมอร์สามารถแสดงได้ว่าคาดหวังการอ้างอิง
nullหรือไม่ - รองรับการแปลงระหว่างประเภทที่มีคุณสมบัติ nullness ต่างกัน และให้คำเตือนสำหรับค่า
nullที่จัดการไม่ถูกต้อง - เข้ากันได้กับโค้ด Java เดิม และรองรับการนำฟีเจอร์ใหม่มาใช้แบบค่อยเป็นค่อยไป
- รับประกันว่าตัวแปรของประเภทที่ปฏิเสธ
nullจะถูกกำหนดค่าเริ่มต้นก่อนถูกอ่านครั้งแรก - บังคับใช้ประเภทที่ปฏิเสธ
nullในรันไทม์ แม้กับคลาสที่คอมไพล์แยกต่างหาก - ให้เมทาดาทาและการรับประกันความถูกต้องที่จำเป็นต่อการปรับแต่งประสิทธิภาพในรันไทม์
สิ่งที่ไม่ใช่เป้าหมาย
- ไม่ตีความโค้ดเดิมใหม่โดยอัตโนมัติ
- ไม่บังคับให้ต้องจัดการค่า
nullทุกกรณีอย่างชัดเจน - ไม่รวมการเปลี่ยนแปลงสำหรับ primitive type
- ไม่นำการปรับปรุงทางภาษาไปใช้กับไลบรารีมาตรฐาน
แรงจูงใจ
- ในโปรแกรม Java ตัวแปรชนิด String สามารถมีได้ทั้งการอ้างอิงถึงอ็อบเจ็กต์ String หรือค่า
null - ไม่มีวิธีแสดงอย่างชัดเจนว่าตัวแปรยอมรับ
nullหรือไม่ จึงก่อให้เกิดความสับสนและบั๊ก - จึงจำเป็นต้องมีเครื่องมือที่ช่วยให้นักพัฒนาระบุได้ว่าไทป์นั้นรองรับหรือคาดหวังค่า
nullเป็นส่วนหนึ่งของประเภท
คำอธิบาย
คุณสมบัติ nullness และตัวทำเครื่องหมาย
- ประเภทอ้างอิงสามารถแสดง nullness ได้แบบเลือกใช้
Foo!คือประเภท null-restricted ที่ไม่รวมnullFoo?คือประเภท nullable ที่รวมnull- โดยค่าเริ่มต้น
Fooจะไม่ได้ระบุ nullness
การกำหนดค่าเริ่มต้นของฟิลด์และอาร์เรย์
- ฟิลด์หรืออาร์เรย์แบบ null-restricted ต้องถูกกำหนดค่าเริ่มต้นก่อนใช้งานเสมอ
- หากพยายามอ่านฟิลด์ null-restricted ที่ยังไม่ได้กำหนดค่าเริ่มต้น จะเกิดข้อยกเว้น
nullness ของนิพจน์และการแปลง
- คอมไพเลอร์ Java จะกำหนด nullness ให้กับทุกนิพจน์
- สามารถใช้การแปลง nullness เพื่อจัดการนิพจน์ที่มี nullness ต่างกันได้
- การแปลง nullness แบบ narrowing อาจทำให้เกิด
NullPointerExceptionในรันไทม์
การตรวจสอบ null ในรันไทม์
- เมื่อเกิดการแปลง nullness แบบ narrowing จะเกิด
NullPointerException
nullness ของตัวแปรประเภท
- ตัวแปรประเภทก็สามารถแสดง nullness ได้
- ตัวแปรประเภทแบบ null-restricted และ nullable ใช้ยืนยัน nullness เฉพาะภายในโค้ด generic
type argument และขอบเขต
- type argument สามารถแสดง nullness ได้ และสิ่งนี้มีผลต่อ nullness ของ API
- type argument ที่มี nullness ไม่ตรงกันอาจทำให้เกิดคำเตือน
การ override เมธอดและการอนุมาน type argument
- nullness จะถูกละเลยเมื่อใช้ตัดสินว่าเมธอดมีซิกเนเจอร์เหมือนกันหรือไม่
- ประเภทคืนค่าของเมธอดที่ override สามารถแปลงได้ผ่านการแปลง nullness
คำเตือนจากคอมไพเลอร์
- การสร้างประเภท null-restricted อาจทำให้เกิดข้อผิดพลาดใหม่ในช่วงคอมไพล์
- การแปลง nullness แบบ narrowing หรือการใช้ประเภท
?กับการดำเนินการที่ไม่เป็นมิตรกับnullอาจทำให้เกิดคำเตือน
การคอมไพล์และการแทนค่าในคลาสไฟล์
- ตัวทำเครื่องหมาย null ส่วนใหญ่จะถูกลบออกจากคลาสไฟล์
- แอททริบิวต์
NullRestrictedใหม่ใช้ระบุว่าฟิลด์ไม่ยอมรับค่าnull
Core Reflection
- ไม่มีลิเทอรัล
Foo!.classหรือFoo?.class - API ใหม่
RuntimeTypeใช้อธิบายรูปแบบ null-restricted ในรันไทม์
การเปลี่ยนแปลงเพิ่มเติม
- การซีเรียลไลซ์แบบดั้งเดิมไม่เข้ากันกับฟิลด์และอาร์เรย์แบบ null-restricted
javadocจะรวมตัวทำเครื่องหมาย nullness- API ของ
java.lang.reflect.Typeและjavax.lang.modelจะเข้ารหัส nullness
ทางเลือก
- เครื่องมือพัฒนาต่าง ๆ ในระบบนิเวศของ Java ต่างก็มีการติดตาม
nullในแบบของตนเอง - ภาษาโปรแกรมอื่น ๆ ติดตาม nullness ในระบบประเภท
- การบังคับใช้ nullness ในรันไทม์สามารถทำได้ด้วยการตรวจสอบแบบชัดเจนหรือการเรียก
Objects.requireNonNull
การพึ่งพา
- ต้องใช้ Flexible Constructor Bodies (Second Preview)
- รวมถึงงานในอนาคตอย่าง Null-Restricted Value Class Types (Preview) และ JEP 402: Enhanced Primitive Boxing (Preview)
สรุปของ GN⁺
- JEP นี้มอบเครื่องมือสำหรับจัดการค่า
nullใน Java ได้อย่างชัดเจน ช่วยเพิ่มเสถียรภาพและความอ่านง่ายของโค้ด - การเพิ่มประเภท null-restricted และ nullable ช่วยลดบั๊กที่เกิดจากการอ้างอิง
null - เข้ากันได้กับโค้ดเดิมและนำมาใช้แบบค่อยเป็นค่อยไปได้ ทำให้นักพัฒนามีความยืดหยุ่น
- เมื่อเทียบกับภาษาอื่น ก็ช่วยเสริมความสามารถของ Java ในการจัดการ
null - เครื่องมือที่มีความสามารถคล้ายกันคือฟีเจอร์ null-safety ของ Kotlin
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
การเปรียบเทียบวิธีจัดการ
nullของ C# และ Kotlinlateinit varความเห็นต่อข้อเสนอใหม่
ความกังวลเกี่ยวกับการแปลง nullness-narrowing อัตโนมัติ
ความจำเป็นของวิธีทำให้ตัวแปรทั้งหมดเป็น non-null โดยค่าเริ่มต้น
ความจำเป็นของฟีเจอร์ optionality แบบ explicit ในระดับภาษาใน Java
คำวิจารณ์ต่อการตัดสินใจที่ไม่ใช้การปรับปรุงภาษาเหล่านี้กับ standard library
ความจำเป็นของวิธีง่าย ๆ ในการยกระดับคำเตือนตอน compile time ให้เป็นข้อผิดพลาด
ความจำเป็นที่ค่าเริ่มต้นควรเป็น non-nullable, immutable และมีขอบเขตแคบ
ประสบการณ์การจัดการ
nullในภาษา Hackคำถามว่าสามารถนำฟีเจอร์นี้ไปใช้กับ Java SDK ได้หรือไม่
ลิงก์ที่เกี่ยวข้อง