Try-with-resources statement ปรับปรุงใน Java 9 หากมี resource ที่เป็น final หรือเทียบเท่า final variable แล้ว สามารถใช้ variable นั้นใน try-with-resources ได้โดยไม่ต้อง declare ใหม่ใน try block
สามารถประกาศ multiple resources ใน try block ได้ Try initialization block รองรับ resources หลายตัว ทั้ง null และ non-null
ตัวอย่างโค้ด
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public class MultipleResourcesTest {
public static void main(String args[]) throws IOException {
System.out.println(readData("test"));
}
static String readData(String message) throws IOException {
try (Reader inputString = new StringReader(message);
BufferedReader br = new BufferedReader(inputString)) {
return br.readLine();
}
}
}
ผลลัพธ์
test
การปรับปรุงจาก Java 7/8
| Version | Syntax | Example |
|---|---|---|
| Java 7/8 | ต้อง declare variable ใหม่ใน try | try (Reader r = new StringReader(s); BufferedReader br = new BufferedReader(r)) |
| Java 9+ | ใช้ existing final/effectively final variables ได้ | Reader r = new StringReader(s); try (r; BufferedReader br = new BufferedReader(r)) |
ตัวอย่าง Java 9 Style (ใช้ existing variables)
public class ImprovedTryWithResources {
public static void main(String[] args) throws IOException {
// Variables declared outside - effectively final
Reader inputString = new StringReader("test data");
BufferedReader br = new BufferedReader(inputString);
// Use in try-with-resources (Java 9+)
try (inputString; br) {
System.out.println(br.readLine());
}
// ทั้ง inputString และ br ถูก close อัตโนมัติ
}
}
กฎสำคัญ
- Variables ต้องเป็น final หรือ effectively final (ไม่ถูก reassign)
- Resources ต้อง implement AutoCloseable หรือ Closeable
- Resources ปิดในลำดับย้อนกลับ (LIFO) - สร้างล่าสุด ปิดก่อน
- ถ้า resource construction ล้มเหลว Resources ที่สร้างแล้วจะถูกปิด
- Exception จาก try block และ exception จาก close() - ตัวแรกเป็น primary, ตัวหลังเป็น suppressed
Multiple Resources Patterns
// Pattern 1: Declare all in try (traditional, still works)
try (FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos)) {
// copy logic
}
// Pattern 2: Use existing variables (Java 9+)
FileInputStream fis = new FileInputStream("a.txt");
FileOutputStream fos = new FileOutputStream("b.txt");
try (fis; fos) {
// copy logic
}
// Pattern 3: Mix of new and existing
Reader reader = new StringReader(data);
try (reader; BufferedReader br = new BufferedReader(reader)) {
// process
}
Suppressed Exceptions
try (Resource r = new Resource()) {
throw new IOException("Primary exception");
} catch (IOException e) {
for (Throwable suppressed : e.getSuppressed()) {
System.out.println("Suppressed: " + suppressed);
}
}
// Output: Suppressed: java.lang.Exception: Resource close failed