java – What is the use of try .. finally without the catch clause?

Question:

I maintain a legacy system, and I have seen in many places a block similar to the following:

try {
  // aqui codigo

} finally {
  // mas codigo aqui
}

My question is: What is the function of doing a try .. finally , without the catch block?

Answer:

Contracts are a common concept in algorithm correctness design and analysis. The concept is that the functions, methods or other units of our programs must have:

  • Preconditions: Conditions that callers must provide in advance for the method to produce correct results;
  • Postconditions: Conditions that (given the preconditions) the method promises will be met when it returns;
  • Invariants: Conditions that the method promises it will not affect — will be true or false upon return if and only if they were true upon entry.

In this framework, the try { ... } finally { ... } is a useful construct so that our code can guarantee postconditions even when there are exceptions within the try { ... } block or in any method invoked within this block. Since the commands inside the finally { ... } block will always be executed, exception or not, it is common to put code there that guarantees the postconditions.

The examples of "cleanliness" that others have given fall within this framework. The idea is that in these examples:

  1. A resource such as a file or a connection to a database is used;
  2. There is a postcondition that forces the code in the example to guarantee that the resource will be closed no matter what happens in its use.

This was the most common use of finally in older versions of Java. In Java 7 a new construct was introduced, called "try with resources," which supplants try { ... } finally { ... } in its most common uses:

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

Another kind of example is with the thread synchronization tools ("threads"). In thejava.util.concurrent.locks package there are several classes of locks that are commonly used with 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

But the concept of postconditions should be emphasized again. After all, try { ... } finally { ... } is not specifically a "cleanup" mechanism but rather a general tool to help you compose correct programs. So it has other uses, even if they are much less common than these two.


Other types of examples should be added. A frequent cause of programming errors is the "early return" of a function or method. Typical cases are something like this:

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));
}

Assuming that we always need to call the cosaQueSiempreTieneQuePasar() method, this example has an error: when I noSéQué() returns with true we cosaQueSiempreTieneQuePasar() early and forget to call cosaQueSiempreTieneQuePasar() . A solution in many cases is the following:

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);
    }
}

And here it should be noted that, although many answers have mentioned exceptions as the reason for the try {...} finally {...} , this example shows that we can run into problems even if there are no exceptions. Other examples are possible with break and continue in repeating structures like for (...) {...} .

Or rather, exceptions, early return , break and continue have something in common — early exit from a block of code — and finally is a common solution to the problems that all of these cause.

Scroll to Top