เมื่อวานเห็น code ที่น่าสนใจเกี่ยวกับเรื่อง Null Pointer Exception (NPE)
มีทั้งทำให้เกิด หรือ ไม่เกิด
แต่ประเด็นเหล่านั้นไม่น่าสนใจเท่ากับว่า
วันนี้ Java Developer ทำการจัดการกับ NPE กันอย่างไร ?
โดยปกติแล้ว NPE จะถูกโยนออกมาเมื่อ
ทำการเรียกใช้งานหรือเข้าถึง object ที่อ้างอิงไปยัง null ที่สำคัญ NPE มันคือ RuntineException ด้วย (Unchecked Exception) นั่นหมายความว่าจะไม่เกิดตอน compile time ดังนั้น compiler จะไม่ทำการเตือนนะ จะเกิดตอน runtime หรือตอนที่ทำงานจริง ๆ !! น่ากลัวมาก ๆใครบ้างที่เจอ NPE บน production ? แต่น่าจะเป็นคำถามที่ผิด น่าจะต้องถามใหม่ว่า ใครไม่เคยเจอบ้าง ? คำถามที่น่าสนใจกว่าคือ จัดการกับ NPE กันอย่างไร ?
วิธีการที่ 1 เห็นได้ทั่วไป มันดักทุกสิ่งอย่าง
บางครั้งไม่รู้ด้วยซ้ำว่าจะดักอะไร แต่เพื่อความสบายใจใส่ไว้ก่อน [gist id="092191a351aec1a7e75b10a1b1a13d68" file="1.java"]วิธีการที่ 2 ตรวจสอบก่อนใช้งานเสมอ
เราจะพบเจอ code เหล่านี้ได้เกลื่อนกลาดในระบบ เรียกว่าลูกอีช่าง if [gist id="092191a351aec1a7e75b10a1b1a13d68" file="2.java"]วิธีการที่ 3 บางคนบอกว่า if-else มันยาวไป ดังนั้นใช้ Ternary operator ก็แล้วกัน
ไม่รู้ว่ามันจะแถไปไหน !! [gist id="092191a351aec1a7e75b10a1b1a13d68" file="3.java"]วิธีการที่ 4 รู้ไหมว่า method equals() ถ้าใช้ถูกวิธีมันจะไม่โยน NPE ออกมานะ
ตัวอย่างของการใช้ที่ผิด ก่อให้เกิด NPE ได้ ถ้าไม่ระวัง [gist id="092191a351aec1a7e75b10a1b1a13d68" file="4.java"] ตามจริง compiler มันจะด่านะ ถ้าตอน compile เพิ่ม -Xlint:all เข้าไป หรือถ้าใช้ IDE ดี ๆ มันก็แสดง warning เหลืองด่าอีกด้วย แต่เท่าที่เจอ Developer จะหน้ามึน ทำเป็นมองไม่เห็น แสดงดังรูป ดังนั้นแก้ไขใหม่ซะ จะเป็นดังนี้ [gist id="092191a351aec1a7e75b10a1b1a13d68" file="5.java"] แต่ถ้าใช้ IDE ดี ๆ มันก็จะแนะนำวิธีการแก้ไขให้เพียบนะครับ เอาที่สบายใจกันได้เลย ดังรูปวิธีการที่ 5 รู้ไหมว่า String.valueOf() มันไม่โยน NPE ออกมานะ !!
แต่ส่งค่า String “null” ออกมาแทนนะ แต่ถ้าใช้งาน toString() ก็บ้านใครบ้านมัน [gist id="092191a351aec1a7e75b10a1b1a13d68" file="6.java"]วิธีการที่ 6 สำหรับ method ที่ต้อง return ค่ากลับ จะส่ง null กลับมาทำโล่ห์ทำพระแสงอะไร ?
คนเรียกใช้ต้องมาเสียเวลาตรวจสอบ null อีก ไม่รู้สึกเบื่อหน่ายกันบ้างเลยหรือไง ? ตัวอย่าง ถ้า method ต้อง return ค่าเป็น Collection ออกมา ถ้าไม่มีค่าก็ส่งเป็น Collection ว่าง ๆ กลับมาสิ [gist id="092191a351aec1a7e75b10a1b1a13d68" file="7.java"]สำหรับข้อมูลที่เป็นพวก Map ก็ให้ใช้ containsKey() ก่อนจะดึงข้อมูลนะ ไม่งั้นเดี๋ยวจะเกิด NPE เอาอีกได้
วิธีการที่ 7 ถ้าสาย Java 8 ก็ Optional สิครับ
ว่าแต่ที่ไหนยังไม่ใช้ Java 8 กันบ้างนะ ? หรือ Java Developer บางคนอาจจะถามว่า ใครเขาใช้กัน ? [gist id="092191a351aec1a7e75b10a1b1a13d68" file="8.java"]เรื่องพื้นฐานผ่านไป แล้วมันมีวิธีการอะไรอีก ?
- Assertion ไปเลย
- ใช้ Library ต่าง ๆ เพิ่ม ที่เห็นใช้บ่อย ๆ ก็เช่น StringUtils จาก Apache Common และ Guice เป็นต้น
- ใช้ singleton pattern !!
- ไปเขียน Kotlin กัน
- อื่น ๆ อีกมากมาย