เรื่องของ Exception ตอน 1

Exception

ผมเขียนเกี่ยวกับ Exception ไว้ 3 ตอน คุณสามารถกด Link ด้านล่างเพื่ออ่านที่เกี่ยวกับ Exception ตอนต่างๆได้เลย

Exception คืออะไร Exception คือ อาการผิดปกติหรือสถานะที่ไม่ปกติของโปรแกรมที่ไม่ได้อยู่ในการควบคุมของโปรแกรมส่วนนั้น ตัวอย่างง่ายๆคือ เรียกฟังก์ชั่นอ่านไฟล์แต่เกิดปัญหาคือไฟล์ที่จะอ่านไฟล์นั้นไม่มีอยู่จริง ซึ่งฟังก์ชันอ่านไฟล์เขา Design ไว้แค่อ่านไฟล์ไม่ได้ครอบคลุมถึงการดูแลว่าถ้าเกิดไฟล์ไม่มีอยู่จริงจะต้องทำยังไง ดังนั้นคนที่ Design ฟังก์ชั่นอ่านไฟล์เขาจึงใช้ Feature Exception ทำการส่ง Exception ออกไปบอกว่า “ผมเปิดไฟล์นี้ไม่ได้นะไฟล์นี้ไม่มีอยู่จริงอันนี้ผมไม่สามารถตัดสินใจได้ว่าผมจะทำยังไงเมื่อไฟล์ไม่มีอยู่จริง คุณไปตัดสินใจเอาเองก็แล้วกันว่าจะทำไงต่อ”

ผมเชื่อว่าจะต้องคำถามเกิดขึ้นมาในใจ อ้าวทำไมต้องโยน Exception ออกมาทำไมไม่จัดการมันในฟังก์ชันนั้นเลยล่ะ คำตอบก็ง่ายๆครับคือ เขา Design ให้มันไปใช้ได้หลายที่ ประมาณว่าเขียนฟังก์ชันอ่านไฟล์ที่เดียว คุณสามารถเอาไปใช้ได้กับทุกที่ทุกงาน แต่ละงานอาจจะต้องการการจัดการ Exception ต่างกันเช่น โปรแกรมกระโหลกกะลาของผมเวลาเจอ Exception นี้ผมสั่งให้โปรแกรมมแสดงหน้าจอตลกๆว่า “Correct file path ?” แต่บางโปรแกรมเขาอาจจะเป็น GUI แสนสวยพร้อมบอกว่า คุณเลือกไฟล์ที่ไม่มีอยู่จริงนะพร้อมใจดีให้ User กรอก ตำแหน่งไฟล์ใหม่ หากเราไม่ทำเป็น Exception กลางๆก็เท่ากับว่าเวลามีการแก้ไขวิธีการจัดการปัญหาเราต้องไปแก้ฟังก์ชันอ่านไฟล์ด้วย ซึ่งมันไม่ควรเพราะงานสองงานนั้นแยกเป็นคนะลงาน งานอ่านไฟล์ก็อ่านไฟล์ งานจัดการกับความผิดพลาดก็งานจัดการกับงานผิดพลาด

1
2
3
4
5
6
7
8
9
10
11
// EXAMPLE try catch exception
// from file input stream
try {
File file = new File("/root/text.txt");
IOStream input = FileUtils.openInputStream(file, "UTF-8");
/// do someting with input stream
} catch(FileNotFoundException ex) {
System.out.println("Correct file path ?");
} catch (IOException ex) {
System.out.println("Hey my program have a problem with file");
}

เพิ่มเติม FileUtils เป็น Lib ที่ช่วยเกี่ยวกับการจัดการไฟล์ไม่ว่าเปิด ปิด ลบ หรือ อื่นๆ แนะนำให้ใช้จะได้ไม่ต้องมาจัดการเอง

ประเภทของ Exception

ในภาษาแต่ละภาษาที่มี Feature Exception นั้นมีการแบ่งประเภทไว้แตกต่างกันแต่มันก็มีแนวคิดคล้ายคลึงกันโดยผมขอยึดตามตัวของภาษา Java ละกัน java แบ่ง Exception ออกเป็น 2 พวกใหญ่ๆคือ Check exception กับ Uncheck exception

Image of exception from : /www.tutorialspoint.com

Check Exception คือ Exception ที่เราต้องเตรียมจัดการกล่าวคือคนเขียนฟังก์ชันเขามองดูแล้วว่า เฮ้ยมันจะต้องเกิด Exception พวกนี้ขึ้นมาแน่ๆซึ่งเป็นเหตุปกติที่มาจากการใส่ชื่อไฟล์ไม่ถูกต้อง หรือ ต่างๆนาๆ ที่คุณต้องเตรียมจัดการนะตัวอย่างง่ายๆคือ IOException และ FileNotFoundException เป็น Exception ที่คนเขียนฟังก์ชันอ่านไฟล์บอกเราแล้วว่า มันมีแน่ๆเราจึงต้องเตรียมจัดการมันเหมือน Code ข้างบน

Uncheck exception คือ Runtime exception จากภาพเราจะเห็นว่า Runtime exception ก็เป็นหนึ่งใน Exception ตามการ Inheritance แต่ในส่วนของ Rumtime exception เขาได้เพิ่มความสามารถเวลาโดน check ว่าจะต้อง check ไหมให้ไม่ได้ต้อง check โดยใช้คุณสมบัติ Polymorphism (เริ่มนอกเรื่อง) เอาเป็นว่าไอ Uncheck exception มันเป็น Exception แบบไม่ที่ต้องมาบอกว่าต้องจัดการนะโดยส่วนใหญ่มันเกิดจากความผิดพลาดของคนเขียน Code ตัวอย่างง่ายๆคือ NullPointerException พี่ส่ง Null ไปให้คนอื่นใช้ หรือ InexOutOfBoundException พี่อ้างอิงถึง index ที่เกิน Array คือลองคิดดูว่าถ้าเราบอกว่าต้องจัดการ NullPointerException, InexOutOfBoundException เนี่ย Code เรามันจะวุ่นวายขนาดไหนกัน เขาเลยเอามันมาเป็น Uncheck exception ถ้าคุณเขียน Code ดีพอ Save พอเหตุการณ์พวกนี้มันจะไม่เกิดไอพวกนี้คือสิ่งที่คุณ Control ได้มันเป็นสิ่งที่คุณ Control ได้โดยไม่ต้องบอกให้จัดการ

"สิ่งที่ผมเขียนขึ้นเป็นเพียงความรู้และความเข้าใจของบุคคลเพียงบุคคลเดียว ดังนั้นอย่าเพิ่งเชื่อในสิ่งที่ผมเขียนและอธิบาย ลองทำความเข้าใจว่ามันเป็นจริงอย่างนั้นไหมและลองหาแหล่งอ้างอิงอื่นๆว่าเขามีแนวคิดอย่างไร เรื่องการ Design และวิธีการใช้งานไม่มีถูกไม่มีผิดมีแต่เหมาะสมกับงานนั้นไหม"

Ref :
https://community.oracle.com/docs/DOC-983543
http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html
https://www.tutorialspoint.com/java/java_exceptions.htm