Для того, чтобы он используется try. finally без статьи catch?

Я делаю содержание полученной в наследство системы, и увидел во многих частях один блок, сходный с тем, что он продолжает:

try {
  // aqui codigo

} finally {
  // mas codigo aqui
}

Мой вопрос: Каковой состоит функция в том, чтобы делать один try .. finally, без блока catch?

5
задан 13.02.2016, 06:53
7 ответов

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

  • Предварительные условия: Условия, которые llamantes должны поставлять заранее для того, чтобы метод произвел правильные результаты;
  • Постусловия: Условия, которые (данные предварительные условия) метод обещает, встретятся, когда он возвратится;
  • Неварианты: Условия, что метод обещает, что он не затронет — они будут верными или фальшивыми, возвратившись если и только, если это это были, войдя.

В этой раме, try { ... } finally { ... } это полезное сооружение для того, чтобы наш код смог гарантировать постусловия даже если встретились исключения внутри блока try { ... } или в любом методе, призванном внутри этого блока. Ввиду того, что команды внутри блока finally { ... } всегда они будут работать, исключение или нет, общо помещать там код, который гарантирует постусловия.

Примеры "чистоты", которую другие дали, падают внутри этой рамы. Идея, чем в этих примерах:

  1. Используется ресурс такие как файл или связь в базу данных;
  2. Существуй постусловие, которое вынуждает к коду примера гарантировать, что ресурс закроется, не важно, чтобы он произошел в Вашем использовании.

Это было использование больше общо finally в старых версиях Java. В Java 7 ввел новое сооружение, названное "try with resources," который он искажает try { ... } finally { ... } в Ваших самых общих использованиях:

try (OutputStream out = ...) {
    // usar el OutputStream `out`
} // postcondición: `out` ha sido cerrado

Другой класс примера - с программными средствами синхронизации между трэдами ("threads"). В пакете java.util.concurrent.locks существуют несколько классов замков ("locks"), что обычно используются с try {...} finally {...}:

Lock l = ...;
l.lock();
try {
    // Entre los hilos que comparten la cerradura `l`, sólo uno
    // puede entrar en este bloque a la vez.
} finally {
    l.unlock();
}  // postcondición: la cerradura está abierta

Но нужно нажимать снова концепцию постусловий. В конце концов, try { ... } finally { ... } это не специально механизм "чистоты" а общего инструмента, чтобы облегчать состав правильных программ. Так что у него есть другие использования, еще, если гораздо менее общие, чем эти два.


Нужно добавлять другой тип примеров. Частая причина ошибок программирования - ранний вывод ("early return") функции или метода. Типичные случаи - нечто похожее:

public LoQueSea miMétodo(Desto algo, Coso queSéYo) {
    // muchas lineas...

    if (noSéQué()) {
        return new LoQueSea(algo);  // salida temprana
    } 

    // muchas más lineas...

    cosaQueSiempreTieneQuePasar(queSéYo);
    return new LoQueSea(algo.con(queSéYo));
}

Предполагая, что всегда нам необходимо называть метод cosaQueSiempreTieneQuePasar(), у этого примера есть ошибка: когда noSéQué() возвратись с true мы выходим ранними и забываем позвонить cosaQueSiempreTieneQuePasar(). Решение во многих случаях - следующее:

public LoQueSea miMétodo(Desto algo, Coso queSéYo) {
    try {
        // muchas lineas...

        if (noSéQué()) {
            return new LoQueSea(algo);  // salida temprana
        } 

        // muchas más lineas...
        return new LoQueSea(algo.con(queSéYo));
    } finally {
        // Este bloque se ejecuta siempre, aun si hay 
        // salida temprana.
        cosaQueSiempreTieneQuePasar(queSéYo);
    }
}

И здесь удар шаром закрепит, что, несмотря на то, что много ответов упомянули об исключениях как мотив для try {...} finally {...}, этот пример показывает, что мы можем сталкиваться с проблемами даже, если нет исключений. Другие примеры возможные с break и continue в структурах повторения как for (...) {...}.

Или скорее, исключения, return рано, break и continue они есть что-то общим — ранний вывод блока кода — и finally это общее решение для проблем, которые вызывают все эти.

9
ответ дан 24.11.2019, 14:53

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

Пример 1

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
} 

Пример 2

OutputStream os = null;
OutputStreamWriter wos = null;
try { 
   os = new FileOutputStream(...);
   wos = new OutputStreamWriter(os);
   // ......

   wos.flush();
   os.flush();
finally {
   IOUtils.closeQuietly(wos);
   IOUtils.closeQuietly(os);
}

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

InputStream in = null;
try {
    in = new FileInputStream("file.txt");
    // Hacer algo que lance una excepción
} finally {
    if (in != null) {
         try {
             in.close();
         } catch (IOException e) {
         // Nothing we can do.
         }
    }
}
3
ответ дан 24.11.2019, 14:53
  • 1
    +1, из-за того, что включает примеры с streams. est и # 225; ndar из факта для finally - liberaci и # 243; n ресурсов со стороны aplicaci и # 243; n. – Paul Vargas 12.02.2016, 23:48

Блок catch служи для того, чтобы поймать только какое-то исключение, которое появлялось бы в течение выполнения кода. Так как нет блока catch, исключение прыгнет и ею будет манипулировать клиент метода, где находился этот блок кода. Если нет никакого управления этого исключения, тогда исключение прыгнет до самого высокого уровня, который сможет достигать. Если самый высокий уровень - метод public static void main(String[] args) приложения и там он не справляется, тогда приложение покажет исключение, которое бросилось, и "закончится".

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

Используй try-finally когда твой код не нуждается в том, чтобы манипулировать исключением, потому что уже существует другой уровень, где он справится. Например, в Веб приложении, где у тебя есть какой-то компонент, у X, которые украшают компоненты, которые выполняют просьбы, и X, уже есть способ работать назначенные по умолчанию исключения, которая автоматически они идет в logear, и он покажет "красивое" сообщение пользователю (я не знаю, какое сообщение ошибки красивое в действительности). Пример этого примера (стойте излишек) - случай Спринг MVC, где ты можешь использовать @ControllerAdvice чтобы манипулировать исключениями на общем уровне. Таким образом, если твой код бросит исключение, ею не будет манипулировать он а класс, украшенный с этой аннотацией.

Это не плохая практика, это тема команды.

2
ответ дан 24.11.2019, 14:53

Поскольку уже упомянули другие люди, try с finally служит для того, чтобы сделать чистоту в случае, что произошла одна excepciГіn, без разбивать эту excepciГіn.

Начиная с Java 7, что у тебя есть try with resources , уже могут существовать даже блоки, которые Гєnicamente включают try:

try (OutputStream s = getOutputStream()) {
    //usar s
}

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

1
ответ дан 24.11.2019, 14:53

PodrГ, - чтобы использовать в процессах, которые, если они не удаются, не надо сообщить ему, ни предупреждать пользователя. но это плохая практика, mГ-nimo deberГ, - чтобы записывать log исключений в catch

0
ответ дан 24.11.2019, 14:53
  • 1
    Если он отпускает excepci и # 243; n, этот detendr и # 225; ejecuci и # 243; n stack, и если он не захватывается в ning и # 250; n сторона так как excepci и # 243; n показывать и # 225; в пользователя aplicaci и # 243; n. –  12.02.2016, 19:51

Полная статья: Try, Catch and Finally. Возможно, что они не использовали блок задержания ошибки, так как не было необходимо реализовывать какой-то тип извещения... Однако, ты был бы должен добавлять это, чтобы, в будущем, идентифицировать лучше почему и, где происходит проблема.

0
ответ дан 24.11.2019, 14:53
  • , Чтобы закрывать ресурсы (p.e. открытые файлы), не прерывая разгрузки запуска исключений, когда случается какая-то.
  • , Чтобы помещать в этот блок код, который мы всегда хотим, чтобы он работал, независимо, если бросаются исключения или нет, p.e.: System.out.println("Salgo de la funcion Clase1.pepito()");
0
ответ дан 24.11.2019, 14:53

Теги

Похожие вопросы