Как автоматически закрывать ресурсы
Короткий ответ
Объявите ресурс в скобках после try. Java вызовет у него close() при выходе из блока — даже если случилось исключение:
void main() throws IOException {
Files.writeString(Path.of("data.txt"), "line 1\nline 2\n");
try (BufferedReader reader = Files.newBufferedReader(Path.of("data.txt"))) {
IO.println(reader.readLine());
}
}Результат:
line 1Несколько ресурсов
Перечислите ресурсы через точку с запятой. Закрываются они в обратном порядке:
void main() throws IOException {
Files.writeString(Path.of("in.txt"), "hello\n");
try (var reader = Files.newBufferedReader(Path.of("in.txt"));
var writer = Files.newBufferedWriter(Path.of("out.txt"))) {
writer.write(reader.readLine().toUpperCase());
}
IO.println(Files.readString(Path.of("out.txt")));
}Результат:
HELLOСвой ресурс
Любой класс, реализующий AutoCloseable, можно использовать в try:
class Connection implements AutoCloseable {
Connection() {
IO.println("open");
}
@Override
public void close() {
IO.println("close");
}
}
void main() {
try (var connection = new Connection()) {
IO.println("work");
throw new IllegalStateException("failed");
} catch (IllegalStateException e) {
IO.println("caught: " + e.getMessage());
}
}Результат:
open
work
close
caught: failedОбратите внимание на порядок: ресурс закрывается до того, как выполняется catch.
Частая ошибка
Закрывать ресурс вручную в конце try. Если раньше произойдёт исключение, close() не вызовется:
class Connection implements AutoCloseable {
@Override
public void close() {
IO.println("close");
}
}
void main() {
try {
var connection = new Connection();
Integer.parseInt("x");
connection.close();
} catch (NumberFormatException e) {
IO.println("error, connection left open");
}
}Результат:
error, connection left openФункции из этого ответа
- try / catch / finally — Перехватывает исключения; finally выполняется всегда, а try с ресурсами сам их закрывает.
- AutoCloseable — Интерфейс ресурса, который можно закрыть в try-with-resources.
- BufferedReader — Читает текст построчно с буферизацией — классический способ обработки больших файлов.