จากงาน Java Boot Camp ผมได้แบ่งปันเรื่องเกี่ยวกับ Clean Code
หนึ่งในนั้นก็คือ การดักจับ exception ในภาษา Java
ผมแนะนำว่าให้ใช้ RuntimeException หรือ Unchecked Exception กันเถอะ
หลังจากนั้นมีหลายคนเดินเข้ามาสอบถามว่ามันคืออะไร
เพราะว่า ปกติใช้แต่ Checked Exception กัน
ดังนั้น ผมจึงมาขออธิบายรายละเอียดเพิ่มเติมให้

ก่อนอื่นมาทำความเข้าใจกับ Checked  และ Unchecked Exception กันก่อน

เรื่องนี้เหมือนว่าเป็นเรื่องที่ใกล้ตัว
คิดว่า java programmer ส่วนใหญ่จะรู้จักและเข้าใจ
แต่ในความเป็นจริงไม่ได้เป็นเช่นนั้นเลย เพราะว่า นับหัวได้เลยที่รู้จักและเข้าใจ
ดังนั้นมาทำความเข้าใจกันนิดหน่อย

Checked Exception คืออะไร

ง่ายๆ ก็คือ Exception ที่เราๆ ท่านๆ ต้องใช้ try-catch ในการดักจับนั่นแหละครับ
ซึ่งมันจะดักจับในขณะ compile time นั่นเอง
ดังนั้น ถ้าใน code มีการโยน Checked Exception ออกมา
แต่ไม่มี try-catch ดักจับ ก็จะทำให้ไม่สามารถ compile code ได้นะ

ตัวอย่าง code การเชื่อมต่อฐานข้อมูลผ่าน JDBC

คำอธิบาย
การติดต่อฐานข้อมูลผ่าน JDBC นั้นจะโยน SQLException ออกมาเสมอ
เมื่อการทำงานผิดพลาด ซึ่ง SQLException นั่นคือ Checked Exception นั่นเอง

โดยสามารถสรุปให้ได้ว่า Checked Exception คือ
class ใดๆ ก็ตามที่เป็น class ลูกของ class Exception
แต่ไม่สืบทอดมาจาก class RuntimeException

Unchecked Exception คืออะไร

มันก็ตรงข้ามกับ Checked Exception ไงล่ะ !!
นั่นก็คือ จะไม่ทำการตรวจสอบในขณะ compile นะ
โดย Unchecked Exception ถูกใช้

  • ในการเข้าถึง method ต่างๆ ใน object คือ NullPointerException
  • ในการเข้าถึงตำแหน่งที่ไม่มีอยู่ใน array คือ ArrayIndexOutOfBoundException

Unchecked Exception นั้นจะต้องสืบทอดมาจาก class RuntimeException
ซึ่งประโยชน์ของมันก็คือ ทำให้ code ที่เขียนขึ้นมาอ่านง่าย เข้าใจง่าย ซึ่งเป็นหนึ่งแนวทางใน Clean code นั่นเอง

มาถึงตรงนี้อาจจะจินตนาการภาพไม่ออก

ผมจึงวาดรูปแสดงลำดับชั้นของ class ให้ดูดังรูป

  • สีแดงคือ Checked Exception
  • สีเขียวคือ Unchecked Exception

Screen Shot 2557-09-01 at 8.37.18 PM

ควรใช้ Checked Exception เมื่อไรดีล่ะ

สำหรับ Java นั้นมักพบว่ามีการใช้งาน Checked Exception บ่อยมาก
เนื่องจากเราต้องการ code ที่มีความน่าเชื่อถือและความมั่นใจ
สามารถคืนสู่สภาพเดิม (recovery) ได้หลังจากเกิด Exception ขึ้นมา

แต่ผลที่ตามมาก็คือ ทำให้เกิด code ที่รกรุงรัง
หรือเป็น code ที่ไม่น่าจะมีขึ้นมาเลย เช่นการดัก try-catch และ throws Exception ออกจาก method
แต่ก็ถูกแก้ไขไปบ้างตั้งแต่ Java 7

Checked Exception จะถูกใช้งานดังนี้

  • การกระทำต่างๆ ที่อาจจะทำให้เกิดระบบเสียหายได้ เช่น I/O (อ่านเขียนไฟล์), ฐานข้อมูล และระบบ network เป็นต้น
  • งานที่คุณรู้ว่าจะทำอะไร เมื่อเกิด Exception ต่างๆ ขึ้นมา เช่น business process เป็นต้น
  • ต้องการให้ Compiler ตรวจสอบและบอก programmer ให้รู้ตั้งแต่เวลา compile

แล้วควรใช้ Unchecked Exception เมื่อไรดีล่ะ

ทางที่ดีกว่าสำหรับการจัดการ Exception ในภาษา Java ก็คือ การหุ้ม Checked Exception ด้วย Unchecked Exception

ตัวอย่างเช่น
ใน Data Access Object (DAO) นั้น น่าจะมีการติดต่อฐานข้อมูล
ซึ่งจะโยน SQLException ออกมาเสมอ ซึ่งเป็น Checked Exception
แต่การที่จะโยน SQLException ออกมาจาก DAO ไปยังส่วนของ business process มันก็ไม่น่าจะดูดีเท่าไรนัก
ซึ่งตรงนี้เราสามารถห่อหุ้ม SQLException ไปไว้ใน Unchecked Exception ได้ เช่น RuntimeException เป็นต้น

แสดง code ตัวอย่างดังนี้

คำอธิบาย

  • InsertException คือ class ที่เป็นสืบทอดมาจาก RuntimeException นั่นเอง
  • ไม่มี throws Exception ตรง signature ของ method ด้วยนะครับ

โดยสรุปแล้ว

  • ทั้ง Checked  และ Unchecked Exception ต้องดักจับด้วย try-catch-finally นะ ( ใน Java 7 ขึ้นมาไม่ต้องใช้ finally แล้วนะ)
  • Checked Exception ถูกตรวจสอบตั้งแต่ compile time
  • Uncheck Exception มักถูกใช้งานสำหรับการดักจับข้อผิดพลาดที่เราพัฒนาขึ้นมา เกิดในขณะ Runtime หรือตอนทำงานนั่นเอง
  • การใช้งานจริง ๆ นั้น ปกติผมจะใช้ Checked exception สำหรับจัดการ exception จากภายนอก ส่วน Unchecked exception สำหรับจัดการจากภายใน ยกตัวอย่างเช่น จัดการกับ database คือภายนอก จึงใช้งาน Checked exception ส่วนการเรียก code กันภายใน project จะใช้ Unchecked exception เป็นหลัก

ดังนั้น ลองเลือกและนำไปใช้ดูครับ ว่า code ของคุณ มันดูสะอาดขึ้นไหม ?