Оператор try c ресурсами

417
27 января 2017, 05:55

Зачем нужен усовершенствованный и появившийся в JDK 7 оператор try-c-ресурсами?

try (спецификация_ресурса) {
//использование ресурса
{
Answer 1

Оператор try-c-ресурсами реализует принцип автоматического управления ресурсами, целью которого является избежать, например, утечек памяти, в случаях когда ресурс по каким-то причинам не освобождается, если он больше не нужен.

Неудачный исход закрытия файла может привести к "утечкам памяти", поскольку неиспользуемые ресурсы оперативной памяти останутся выделенными.(стр 365)

try ( FileInputStream res = new FileInputStream(args[O])) {
    //использование ресурса
}

Оператор try-c-ресурсами позволяет объявить и проинициализировать ресурс (в круглых скобках после оператора try), создав переменной ресурса локальный контекст в блоке try. По завершении этого блока переменная удаляется, а значит и ресурс автоматически закрывается.

Отсюда отпадает необходимость явного закрытия ресурса методом close() в блоке оператора finally.

Answer 2

try-catch with resources был придумал лишь для того, чтобы избежать шаблонного кода.

Давайте попробуем написать, простой метод, для чтения первой строки из файла. До java 7 он выглядел бы следующим образом:

private static String readFirstLine(String fileName) {
    BufferedReader reader = null;
    String line = null;
    try {
        reader = new BufferedReader(new FileReader(fileName));
        line = reader.readLine();
        reader.close();
    } catch (IOException e) {
        try {
            reader.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
    return line;
}

Заметили, что в блоке catch нам нужен еще один блок для обработки исключений, т.к. мы должны закрыть ресурс, но операция закрытия в свою очередь тоже может выбросить исключение.

Не стоит так же забывать, что try-catch with resources позволяет не думать об освобождении ресурсов. Как только выполнение программы покидает область видимости ресурса/ресурсов, у них автоматические вызывается метод java.lang.AutoCloseable.close()

По сути, данную конструкцию можно представить, как метод, который принимает на вход какой то блок кода, требующий выполнения и список ресурсов, которые необходимо освободить после его выполнения.

private static void invoke(Callable<Void> task, Closeable... resources) throws Exception {
    Exception exception = null;
    try {
        task.call();
    } catch (Exception e) {
        exception = e;
    } finally {
        for (Closeable closeable : resources)
            try {
                closeable.close();
            } catch (Exception e) {
                if (exception == null)
                    exception = e;
                else
                    exception.addSuppressed(e);
            }
    }
    if (exception != null)
        throw exception;
}
READ ALSO
Не работает SELECT COUNT(*) в Mybatis

Не работает SELECT COUNT(*) в Mybatis

При выполнении запроса на получение количества записей возникает ошибка

432
Как добавить переменную для просмотра в режиме отладки в IntelliJ IDEA?

Как добавить переменную для просмотра в режиме отладки в IntelliJ IDEA?

Как добавить свою переменную для просмотра в режиме отладки в IntelliJ IDEA?

409
VideoView воспроизводит звук без изображения

VideoView воспроизводит звук без изображения

Дело в том, что VideoView с помощью MediaPlayer корректно воспроизводит все видео кроме 4k или Full HD разрешенияТо есть звук идет нормально, а вместо изображения...

397
Сравнение объектов и переменных в Java

Сравнение объектов и переменных в Java

Здравствуйте, постоянно сталкиваюсь с проблемой сравнения объектов или просто переменных, даже одного типаТочнее, элементов разных массивов...

496