Как реализовать `finally` для случая ошибки в Java - PullRequest
1 голос
/ 10 декабря 2010

Мне нужен код для запуска в случае возникновения ошибки. В основном мне нужен блок finally, который выполняется только в случае исключения. Я бы реализовал это так:

HttpURLConnection post(URL url, byte[] body) throws IOException {
    HttpURLConnection connection = url.openConnection();
    try {
        OutputStream out = connection.getOutputStream();
        try {
            out.write(body);
        } finally {
            out.close();
        }
        return connection;
    } catch (Throwable t) {
        connection.disconnect();
        throw t;
    }
}

Выглядит хорошо - за исключением того, что он не скомпилируется: моя функция не может выдать Throwable.

Я мог бы переписать:

    } catch (RuntimeException e) {
        connection.disconnect();
        throw e;
    } catch (IOException e) {
        connection.disconnect();
        throw e;
    }

Но даже тогда я а) пропускаю все ошибки и б) должен исправлять этот код каждый раз, когда я изменяю свою реализацию, чтобы выдавать различные типы исключений.

Можно ли вообще с этим справиться?

Ответы [ 3 ]

11 голосов
/ 10 декабря 2010

Вы можете использовать блок finally и добавить флаг для обозначения успеха.

bool success = false;
try {
    //your code
    success = true;
    return retVal;
} finally {
    if (!success) {
        //clean up
    }
}
3 голосов
/ 10 декабря 2010

Throwable имеет два подкласса, Error и Exception.Javadocs для Error говорит:

Ошибка - это подкласс Throwable, который указывает на серьезные проблемы, которые разумное приложение не должно пытаться отловить .Большинство таких ошибок являются ненормальными условиями.Ошибка ThreadDeath, хотя и является «нормальным» условием, также является подклассом Error, поскольку большинству приложений не следует пытаться ее перехватить.

Поэтому, если это действительно необычная ситуация, вы можете просто сосредоточиться наException:

catch (IOException e) {
    connection.disconnect();
    throw e;
}
catch (RuntimeException e) {
    connection.disconnect();
    throw e;
}
catch (Exception e) {
    connection.disconnect();
    throw new IOException(e);
}
0 голосов
/ 10 декабря 2010

Если я не ошибаюсь, исключению не понадобится блок finally, чтобы остановить выполнение и сделать то, что вам нужно, например очистить или устранить ошибки.

try {
  // Do some work! 
  // Fail
} catch (IOException e) {
  // Clean up, alert user, expected error
} catch (Exception e) {
  // Not so much expected, but lets try to handle this
}

Ошибки должны исходить от ваших реализованных классов и методов, которые в основном являются вашими идеями. Подумайте о ходе выполнения и распространении ошибок. Если ваш приведенный выше метод не перехватывает конкретное исключение, то все, что вызвало его, увидит исключение.

Throwable - это просто класс верхнего уровня с подклассами. Исключение, как правило, подвох. И помните, что вы также можете реализовать свои собственные исключения для решения задачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...