Ответ
Ресурс, объявляемый в try-with-resources, должен реализовывать интерфейс java.lang.AutoCloseable (введен в Java 7) или его более старый подынтерфейс java.io.Closeable.
Почему это требование: Конструкция гарантирует автоматический вызов метода close() для каждого ресурса по завершении блока try, даже в случае возникновения исключения. Наличие интерфейса — это контракт, гарантирующий, что такой метод существует.
Пример корректного использования:
// FileInputStream и BufferedReader реализуют AutoCloseable
try (FileInputStream fis = new FileInputStream("data.bin");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
String line = reader.readLine();
// работа с ресурсами...
} // Здесь JVM автоматически вызовет reader.close(), затем fis.close()
Важные детали:
- Ресурсы закрываются в обратном порядке их создания (LIFO).
- Исключение в блоке
tryи в методеclose()не «гасит» друг друга. Исключение изclose()добавляется как suppressed к основному. - Попытка использовать не-
AutoCloseableресурс приведет к ошибке компиляции.
Ответ 18+ 🔞
Ну слушай, история такая. Чтобы вот эту штуку, try-with-resources, использовать — твой ресурс должен быть не абы каким, а правильным пацаном. А именно — реализовывать интерфейс java.lang.AutoCloseable (его в седьмую джаву запилили) или его старшего брата java.io.Closeable.
А почему, спрашивается? Да всё просто, как три копейки! Эта конструкция — она как надёжный дворник: когда ты закончил свои дела в блоке try (или накосячил и вылетело исключение), она сама, автоматом, вызовет у каждого ресурса метод close(). А интерфейс — это такая бумажка с печатью, которая гарантирует, что метод close() у объекта вообще есть, иначе какой с него спрос?
Вот смотри, как это выглядит, когда всё по-взрослому:
// FileInputStream и BufferedReader — они оба, блядь, AutoCloseable, пацаны проверенные
try (FileInputStream fis = new FileInputStream("data.bin");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
String line = reader.readLine();
// делаем тут свои делишки...
} // А тут JVM, тихим сапом, сама вызовет reader.close(), а потом и fis.close(). Красота!
Ещё пара важных фишек, чтобы не облажаться:
- Ресурсы закрываются в обратном порядке, как таджики на стройке — кто последним пришёл, тот первым идёт мыть полы (LIFO, короче).
- Если исключение вылетело и в блоке
try, и в методеclose()— они друг друга не перекричат. То, что изclose(), прицепится как suppressed к основному, чтоб не потерялось, хитрая жопа. - А если ты попробуешь сунуть в
try-with-resourcesчто-то, что неAutoCloseable— компилятор тебе такую ошибку влепит, что мало не покажется. Ошибка компиляции, Карл! Сразу видно — распиздяй.