LINUX.ORG.RU

Полный аналог try-with-resources

 , , , ,


1

1

Код на ява 1.7 (алгоритм не важен, интересен лишь блок с автозакрытием ресурса):

    private Future<IOException> startStreamPump(final InputStream errorStream) {
        return executor.submit(new Callable<IOException>() {
            @Override
            public IOException call() {
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));) {
                    for (; ; ) {
                        String line = reader.readLine();
                        if (line == null) {
                            break;
                        }
                        synchronized (log) {
                            log.warn(line);
                        }
                    }
                    return null;
                } catch (IOException e) {
                    return e;
                }
            }
        });
    }
Метод reader.close() может бросать IOException.

Какой из этих вариантов будет полным аналогом без использования try with resources? Первый:

    private Future<IOException> startStreamPump(final InputStream errorStream) {
        return executor.submit(new Callable<IOException>() {
            @Override
            public IOException call() {
                BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));
                try {
                    for (; ; ) {
                        String line = reader.readLine();
                        if (line == null) {
                            break;
                        }
                        synchronized (log) {
                            log.warn(line);
                        }
                    }
                    return null;
                } catch (IOException e) {
                    return e;
                } finally {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
    }
Второй:
    private Future<IOException> startStreamPump(final InputStream errorStream) {
        return executor.submit(new Callable<IOException>() {
            @Override
            public IOException call() {
                BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));
                try {
                    for (; ; ) {
                        String line = reader.readLine();
                        if (line == null) {
                            break;
                        }
                        synchronized (log) {
                            log.warn(line);
                        }
                    }
                    return null;
                } catch (IOException e) {
                    return e;
                } finally {
                    try {
                        reader.close();
                    } catch (IOException e) {
                    }
                }
            }
        });
    }
Разница между вариантами лишь в одной строчке - throw new RuntimeException(e); в finally блоке. Или если оба неправильные, какой код будет полным аналогом?

 private Future<IOException> startStreamPump(final InputStream errorStream) {
        return executor.submit(new Callable<IOException>() {
            @Override
            public IOException call() {
                IOException thrown = null;  //<<----
                BufferedReader reader = new BufferedReader(new InputStreamReader(errorStream));
                try {
                    for (; ; ) {
                        String line = reader.readLine();
                        if (line == null) {
                            break;
                        }
                        synchronized (log) {
                            log.warn(line);
                        }
                    }
                } catch (IOException e) {
                    thrown=e;  //схороним первое исключение
                } finally {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        //здесь jvm сделает еще фокус
                        //e.setSupressedException(thrown);

                        thrown=e;  //перетрём исключение
                    }
                    return e;
                }
            }
        });
    }

Подробнее читайте на нашем сайте

anonymous ()

А варианта обновиться до java-8 вообще нет? Там как бы не только сахар... есть ещё всякие там исправления уязвимостей...

BattleCoder ★★★★★ ()
Ответ на: комментарий от BattleCoder

Нет, в этом проекте всё пока ещё на 6-й яве. Интырпрайзный подход, лет 5-7 назад со скрипом переползали с 1.4 на 1.6. Это были лихие 2010-е, мы использовали ретротранслятор как могли. Сейчас же из-за этого уже не первую либу портирую на шестую яву.

orm-i-auga ★★★★★ ()
Последнее исправление: orm-i-auga (всего исправлений: 1)
Ответ на: комментарий от orm-i-auga

Попробуй проект retrolambda. Правда оно вроде как только про лямбды. Что еще умеет - не знаю.

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

TheKnight ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.