คุณต้องเคยเจอ NullPointerException หากเคยทำงานกับ Java-based applications Null Pointer Exception เป็น error ที่พบบ่อยที่สุดในการพัฒนา Java application ปกติมาจาก human error แต่ debugging error แบบนี้อาจใช้เวลานาน ปัญหานี้ไม่ได้เป็น syntactical error ทั้งหมด จึงอาจยากที่จะระบุปัญหาบ้าง
บทความนี้จะดูว่า java.lang.NullPointerException คืออะไร ทำไมเกิดขึ้น วิธีแก้ และ best practices หลีกเลี่ยง wild null pointers มาเริ่มกันเลย
java.lang.NullPointerException คืออะไร?
Null Pointer Exception เป็นหนึ่งในหลาย Exceptions ที่ Java รองรับ แสดงว่ามีการพยายามเข้าถึง reference variable ที่ชี้ไปที่ null อยู่
Null เป็นค่าเริ่มต้น (default value) ใน Java ที่กำหนดให้ตัวแปรที่ยังไม่ได้ initialize โดยผู้ใช้ หลังหรือพร้อมกับการประกาศ ตัวอย่างประกาศตัวแปร:
String str;
ลองพิมพ์เนื้อหาตัวแปร:
System.out.println(str); // => null
เห็นว่า 'null' ถูกพิมพ์ออกมา แสดงว่า str ยังไม่ initialize จึงชี้/เก็บค่า null ปัญหาของ null pointing variable คือ ตัวแปรเป็นแค่ reference ไม่ชี้ไปที่อะไรเลย หากพยายามทำ operation บนข้อมูลใน null pointing variable ระบบจะไม่รู้ทำไง เพราะไม่มีข้อมูลจริงเก็บอยู่ ตัวแปรชี้ไปที่ void entity
ตัวอย่าง java.lang.NullPointer.Exception
หาตัวอย่าง NullPointerException ไมยาก แค่ไม่ initialize ตัวแปร ก่อนเข้าถึง ตัวอย่าง ใช้คลาส StringBuilder ใช้จัดการการสร้างและจัดการ string ปกติใช้แบบนี้:
import java.util.StringBuilder;
public class Test {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("Hello ");
sb.append("World!");
String result = sb.toString();
System.out.println(result); // => Hello World!
}
}
รัน snippet นี้ จะทำงานปกติ มาดูเวอร์ชันปรับแต่งที่จะ throw null pointer exception:
import java.util.StringBuilder;
public class Test {
public static void main(String[] args) {
StringBuilder sb;
sb.append("Hello ");
sb.append("World!");
String result = sb.toString();
System.out.println(result);
}
}
เห็นไหม เราไม่ได้ initialize instance ของ StringBuilder ตอนประกาศ ตอนรัน sb.append() sb ไม่ชี้ไปที่ object จริง แต่ชี้ null นี่คือที่ที่ NullPointerException ถูก throw เนื่องจาก exception ถูก throw JVM ไม่สามารถรัน statement ต่อๆ ไปได้
วิธีแก้ java.lang.NullPointerException Error
สร้าง Null Pointer Exception ง่าย แต่หลีกเลี่ยงหรือแก้ไขยาก แม้ IDE บางตัวจะเตือนถ้าเข้าถึงตัวแปรก่อน initialize ด้วยค่าที่เข้ากันได้ แต่ส่วนใหญ่ IDE ไม่สามารถจับได้ในสถานการณ์ซับซ้อน เช่น ส่งตัวแปรผ่าน multiple method calls วิธีแก้ที่แน่นอน ขึ้นกับ situation และโค้ดของคุณ นี่คือวิธีแก้สถานการณ์ Null Pointer ทั่วไป:
1. ตรวจสอบโค้ดหา Manual Errors
สาเหตุใหญ่ที่สุดของ Null Pointer Exceptions คือ human error ให้แน่ใจว่าโปรแกรมที่เขียน มี logic ถูกต้องตามที่ตั้งใจไว้เริ่มต้น ดูผ่าน source code เช็คว่าไม่ได้พลาด statement ไหน หรือสะกดตัวแปรผิด ทำให้ตัวแปรบางตัวไม่ได้ถูกกำหนดค่า
ให้แน่ใจว่าเขียนโค้ดตาม logic ที่กำหนด ไม่พลาด statements ไม่ได้ assign objects ให้ references ผิด กฎทั่วไป: เช็คว่า ก่อนใช้ตัวแปรใดๆ ตัวแปรนั้นถูก initialize ด้วย object แล้ว
2. ใส่ Safety Checks รอบโค้ดที่อาจก่อให้เกิด Null Pointer Exception
ถ้ารู้บรรทัดโค้ดที่ก่อให้เกิด NullPointer และเชื่อว่า logic ถูกต้องแล้ว สามารถห่อส่วนโค้ดนั้นใน try-catch block และกำหนด behavior เมื่อจับ Null Pointer ได้ โครงสร้างจะเป็นแบบนี้:
... // Some code above
try {
// Put the exception-prone code here
} catch (NullPointerException npe) {
// Define what needs to be done when an NPE is caught
}
// Some code below ...
สถานการณ์นี้เกิดเมื่อ reference variable บางตัว อาจจะมี null หรือไม่มี กรณี responses จาก remote API, device interfaces มักเป็นแบบนี้ ขึ้นกับว่ามีผลลัพธ์หรือ hardware พร้อมใช้งาน response variable อาจจะชี้ไปที่ instantiated object หรือไม่ ใช้ safety checks เหมาะสมที่สุดสำหรับสถานการณ์เหล่านี้
3. เช็ค Null ก่อนเข้าถึง (Null Check)
วิธีนี้คล้าย try-catch ใช้ 'if' block เช็ค null ก่อนเข้าถึงตัวแปร โค้ดก่อนหน้าจะกลายเป็นแบบนี้:
... // Some code above
If (myVar !== null ) {
// Put the success logic here
} else {
// Handle null value here
}
// Some code below ...
ความแตกต่างใหญ่คือ scope ของการเช็ค: if method เช็ค myVar เฉพาะ null values ส่วน try-catch จับตัวแปรที่เป็น null ทั้งหมด
ทำให้ 'if' block เป็น targeted และ clean approach สำหรับรองรับ null pointers ใน application logic แต่ถ้ามีหลายตัวแปรที่อาจเป็น null ใช้ try-catch จะง่ายกว่า
สรุป
บทความนี้ดูว่า Null Pointer Exception ใน Java คืออะไร และ error นี้เกิดยังไง เราดูโค้ดที่ก่อให้เกิด Null Pointer Exception เพื่อเข้าใจว่า Null Pointers สร้างขึ้นในสถานการณ์จริงอย่างไร สุดท้ายเราระบุวิธีแก้ Null Pointer Exception ชั้นนำ และเปรียบเทียบ 2 วิธีแก้ NPEs
หากเขียนโปรแกรม Java Null Pointer Exception เป็นหนึ่งใน essential bugs ที่ต้องรู้วิธีแก้ Exception นี้เป็นปัญหาที่พบบ่อยที่สุด และไม่เกี่ยวกับ syntax หรือ semantics ของโค้ด ทำให้เป็นปัญหาที่ยากที่สุดในการระบุและแก้ไข Quick reference เหมือนบทความนี้ช่วยทำประสบการณ์ให้ราบรื่นขึ้น