Resource คือ object ที่ implement interface AutoCloseable (หรือ Closeable ใน Java 7) เช่น FileInputStream, Socket, Database Connection ควรปิดหลังใช้งานเสมอ
ก่อน Java 7: ใช้ finally block
import java.io.*;
public class OldStyle {
public static void main(String[] args) {
FileInputStream fis = null;
try {
fis = new FileInputStream("D:\\sample.txt");
// use fis...
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
ปัญหา: โค้ดยาว, น่าเบื่อ, อาจลืมปิด, close() เองก็อาจ throw exception
Java 7+: Try-with-resources (ARM)
ARM = Automatic Resource Management ประกาศ resource ใน try block จะปิดอัตโนมัติที่จบ block (แม้มี exception)
Syntax
try (ResourceType resource = new ResourceType()) {
// use resource
} // auto-close here
ตัวอย่าง
import java.io.*;
public class ARMExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("D:\\sample.txt");
Scanner sc = new Scanner(fis)) {
while (sc.hasNextLine()) {
System.out.println(sc.nextLine());
}
} catch (IOException e) {
e.printStackTrace();
}
// fis และ sc ถูกปิดอัตโนมัติที่นี่
}
}
หลาย Resource (Java 7+)
try (FileInputStream in = new FileInputStream("in.txt");
FileOutputStream out = new FileOutputStream("out.txt")) {
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
System.out.println("File copied!");
} // ทั้ง in และ out ปิดอัตโนมัติ (LIFO order)
กฎของ Try-with-resources
- Resource ต้อง implement
AutoCloseable(หรือCloseable) - Resource ถูกประกาศในวงเล็บ
try (...) - ปิดตามลำดับ LIFO (Last In First Out) - ตัวสุดท้ายปิดก่อน
- หากมี exception ใน try block และ exception ใน close() → suppressed exception (เข้าถึงได้ด้วย
getSuppressed()) - Java 9+: สามารถใช้ variable ที่ประกาศนอก try block ได้ (effectively final)
Java 9+ Improvement
// Java 9: ใช้ variable ที่มีอยู่แล้ว (effectively final)
FileInputStream fis = new FileInputStream("file.txt");
try (fis) { // ไม่ต้อง declare ใหม่
// use fis
}
Custom Resource (Implement AutoCloseable)
public class DatabaseConnection implements AutoCloseable {
private Connection conn;
public DatabaseConnection(String url) throws SQLException {
this.conn = DriverManager.getConnection(url);
}
public Connection getConnection() { return conn; }
@Override
public void close() throws SQLException {
if (conn != null && !conn.isClosed()) {
conn.close();
System.out.println("Connection closed");
}
}
}
// ใช้งาน
try (DatabaseConnection db = new DatabaseConnection("jdbc:mysql://...")) {
// use db.getConnection()
} // auto close
สรุป
| วิธี | Java Version | ข้อดี | ข้อเสีย |
|---|---|---|---|
| finally + close() | 1.0 | ควบคุมได้ทุกอย่าง | Verbose, error-prone |
| try-with-resources | 7+ | Concise, safe, auto-close | ต้องเป็น AutoCloseable |
| try-with-resources (multi) | 7+ | หลาย resource พร้อมกัน | - |
| Java 9+ effectively final | 9+ | ใช้ variable เดิมได้ | - |
Best Practice: ใช้ try-with-resources ทุกครั้ง ที่จัดการ resource (IO, DB, Network, Locks)