¿Tiene sentido hacer "try-finally" sin "catch"?

127

Vi un código como este:

    try
    {
        db.store(mydata);
    }
    finally
    {
        db.cleanup();
    }

Pensé que tryse supone que tiene un catch?

¿Por qué este código lo hace de esta manera?

glanden
fuente
1
asegura la limpieza como se menciona en otras respuestas, especialmente para identificadores de archivos fopeno conexión de base de datos (también en PHP)
MediaVince

Respuestas:

182

Esto es útil si desea que el método que se está ejecutando actualmente arroje la excepción y permita que los recursos se limpien adecuadamente. A continuación se muestra un ejemplo concreto de manejar la excepción de un método de llamada.

public void yourOtherMethod() {
    try {
        yourMethod();
    } catch (YourException ex) {
        // handle exception
    }
}    

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}
Taylor Leese
fuente
17
comúnmente utilizado con bloqueos como en: lock.lock (); intente {/ * bloqueado * /} finalmente {lock.unlock ()}
minutos
¿Qué sucede si finalmente se lanza una excepción dentro?
barth
1
@barth Cuando no hay catchbloque, la excepción lanzada finallyse ejecutará antes que cualquier excepción en el trybloque. Entonces, si hay dos excepciones, una en tryy una en finallyla única excepción que se lanzará es la que está adentro finally. Este comportamiento no es el mismo en PHP y Python, ya que ambas excepciones se lanzarán al mismo tiempo en estos lenguajes y el orden de excepciones es tryprimero y luego finally.
Lluvia
72

Está allí porque el programador quería asegurarse de que db.cleanup()se llamara incluso si el código dentro del bloque try arroja una excepción. Las excepciones no serán manejadas por ese bloque, pero solo se propagarán hacia arriba después de que se ejecute el bloque finalmente.

Matti Virkkunen
fuente
23
+1 exactamente. El trysolo está ahí para permitir el finally. No se capturan excepciones.
zockman
2
+1 para dejar en claro que la excepción continúa en la pila hasta que se detecta. Gracias
Code Jockey
20

¿Por qué este código lo hace de esta manera?

Porque aparentemente el código no sabe cómo manejar excepciones a este nivel. Eso está bien , siempre que lo haga una de las personas que llaman, es decir, siempre y cuando la excepción finalmente se maneje en algún lugar.

A menudo, el código de bajo nivel no puede reaccionar adecuadamente a las excepciones porque el usuario debe ser notificado, o la excepción debe registrarse, o debe intentarse otra estrategia. El código de bajo nivel realiza una sola función y no conoce la toma de decisiones de alto nivel.

Pero el código aún necesita limpiar sus recursos (porque si no lo hace, se filtrarían), por lo que hace exactamente eso en la finallycláusula, asegurándose de que siempre suceda, ya sea que se haya lanzado una excepción o no.

Konrad Rudolph
fuente
2

El último bloque asegura que incluso cuando se lanza una RuntimeException (tal vez debido a algún error en el código llamado), se realizará la db.cleanup()llamada.

Esto también se usa a menudo para evitar demasiado anidamiento:

try
{
    if (foo) return false;
    //bla ...
    return true;
}
finally
{
    //clean up
}

Especialmente cuando hay muchos puntos en los que el método regresa, esto mejora la legibilidad ya que cualquiera puede ver que el código de limpieza se llama en todos los casos.

FROTTHOWE
fuente
0

El código lo está haciendo para garantizar que la base de datos esté cerrada.
Por lo general, la forma en que lo haría es poner todo el código de acceso a su base de datos en el bloque try y luego hacer una llamada para cerrar la base de datos en el bloque finalmente.
La forma en que try ... finalmente funciona, significa que el código en el bloque try se ejecuta, y el código en el bloque finalmente se ejecuta cuando eso termina ... pase lo que pase.
A menos que la computadora sea arrancada de la pared, finalmente se ejecutará.
Esto significa que incluso si se llama a una excepción, y el método tarda tres años en ejecutarse, seguirá en el bloque final y la base de datos se cerrará.

chustar
fuente
0

Si alguno de los códigos en el bloque try puede generar una excepción marcada, debe aparecer en la cláusula throws de la firma del método. Si se lanza una excepción no marcada, se elimina del método.

El último bloque siempre se ejecuta, ya sea que se lance una excepción o no.

JARRÓN DELGADO
fuente