ว่าด้วยเรื่องของ Final — Finally — Finalize ใน Java
ในภาษายอดนิยมอย่าง Java (Java 11 ออกมาแล้ว — 09/2018) หลายคน (รวมถึงผมด้วย) ยังสับสนกับ 3 คำที่ขึ้นต้นด้วย “F” ของ Java นั้นก็คือ Final, Finally และ Finalize ว่ามันแตกต่างกันอย่างไร ในบทความนี้จะมาอธิบายแบบเจาะลึกพร้อมทั้งยกตัวอย่างของ 3 คำ นี้ของ Java กันครับ
Final
final keyword (ตัวเล็กเท่านั้น) เป็นคำสงวนใจภาษา Java ซึ่งเราสามารถใช้ได้กับการประกาศ ตัวแปร, method และ class ได้ด้วย โดยที่มันจะมีความหมายแตกต่างกันออกไปขึ้นอยู่กับว่าเราไปใช้ในการประกาศอะไร
final — Variable
เมื่อใช้ final ในการประกาศตัวแปร หรือ variable หลังจากเรากำหนดค่าเริ่มต้นให้กับตัวแปรนั้นแล้ว ต่อไปเราจะไม่สามารภเปลี่ยนแปลงค่านั้นได้อีก
class Foo {
public static void main(String[] args) {
// ประกาศตัวแปร non-final
int a = 5;
// ประกาศตัวแปร final
final int b = 10;
// สามารถเปลี่ยนแปลงค่าของ
// ตัวแปร non-final ได้
a++;
// ไม่สามารถเปลี่ยนแปลงค่าของ
// ตัวแปร final ได้ - จะฟ้อง error ตอน compile
b++;
}
}
final — Method
เมื่อใช้ final ในการประกาศ method จะทำให้ method นั้นไม่สามาถ override ได้ใน subclass นั้นคือถ้าประกาศ method ใน class ด้วย final แล้วจะทำให้ subclass หรือคลาสลูก ไม่สามารถเปลี่ยนแปลงพฤติกรรมของ method นั้นได้
class Foo {
// ประกาศ method ด้วย final
final void x() {
System.out.println("x - Demo");
}
}
class Bar extends Foo {
// ไม่สามารถ override method ที่ประกาศเป็น final
// ใน superclass ได้ - ฟ้อง error ตอน compile
void x() {
System.out.println("x - Bar");
}
}
final — Class
เมือใช้ final ในการประกาศ class จะทำให้ไม่สามารถสืบทอดหรือสร้าง subclass นั้นได้ นั้นคือถ้าประกาส class ด้วย final แล้วจะทำให้ไม่สามารถ extents class นั้นได้
// ประกาศ class ด้วย final
final class Foo {
void x() {
System.out.println("X - Foo");
}
}
// ไม่สามารถ extends class ที่ประกาศเป็น final ได้
// จะฟ้อง error "Cannot inherit from 'Foo'"
class Bar extends Foo {
}
Finally
finally keyword (ตัวเล็กเท่านั้น) เป็นคำสงวนใจภาษา Java ซึ่งเราสามารถใช้ได้กับ บล็อก try/catch เพื่อการันตีว่าส่วนของโค้ดนั้นจะถูก execute อย่างแน่นอน แม้ว่ามีการ thrown exception ก็ตาม ซึ่งส่วนของ finally จะ execute หลังจากที่ส่วนของ try หรือ catch ถูก execute เรียบร้อยแล้ว
class Demo {
static void foo() {
try {
System.out.println("Inside foo");
throw new RuntimeException("demo error");
}
finally {
System.out.println("foo's finally");
}
}
static void bar() {
try {
System.out.println("Inside bar");
return;
}
finally {
System.out.println("bar's finally");
}
}
public static void main(String[] args) {
try {
foo();
}
catch (Exception e) {
System.out.println("Exception caught");
}
finally {
bar();
}
}
}
มีอีกหลายกรณี สามารถดูเพิ่มเติมได้ที่อ้างอิง
Finalize
finalize method เป็น method ใน Garbage Collector ที่จะถูก call เสมอก่อนที่ object จะถูกทำลายซึ่งเป็นกระบวนการของ Garbage Collection ในการทำกิจกรรม clean-up หมายความว่าเป็นกิจกรรมที่จะปิด resource ต่างๆที่เกี่ยวของกับ object ที่กำลังถูกทำลาย ตัวอย่างเช่น Network connection, Database connection หรือเราอาจจะพูดได้ว่าเป็นการ resource deallocation
คำว่า finalize ไม่ใช่ คำสงวนในภาษา Java เหมือน final และ finally
ในเมื่อ finalize method จำเป็นในกระบวนการ Garbage Collection ดังนั้นในทุกๆ object จะมี method นี้เป็นพื้นฐานอยู่แล้ว (เหมือน toString method) ดังนี้
protected void finalize throws Throwable{}
finalize method ที่มีอยู่ในแต่ละ object จะไม่ได้มีการ implementation ดังนั้นในกิจกรรม clean-up เราสามารถทำการ override finalize method ได้ โดยกำหนดกิจกรรมนี้ได้เอง โดยที่ Garbage Collector จะเรียก finalize method ในกิจกรรม clean-up
class Foo {
public static void main(String[] args) {
Foo foo = new Foo();
foo = null;
System.gc();
System.out.println("main completes");
} // override finalize method
public void finalize() {
System.out.println("finalize method overridden");
}
}
จะได้ผลลัพธ์ดังนี้
main completes
finalize method overridden
มีอีกหลายกรณี สามารถดูเพิ่มเติมได้ที่อ้างอิง
สรุป
จากบทความนี้เราได้เห็นความแตกต่างของการใช้งาน final, finally และ finalize แบบคร่าวๆ สามารถดูเพิ่มเติมได้ที่ GeeksforGeeks ด้านล่างนี้