I'm doing maintenance on a legacy system, and I've 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 making a try .. finally
, without the block catch
?
Contracts are a common concept in the design and analysis of the correctness of algorithms. The concept is that the functions, methods or other units of our programs must have:
In this framework, the
try { ... } finally { ... }
is a useful construct so that our code can guarantee postconditions even when exceptions occur within the del blocktry { ... }
or in any method called within this block. Since the commands inside the blockfinally { ... }
are always going to be executed, exception or not, it is common to put code there that guarantees postconditions.The examples of "cleaning" that others have given fall within this framework. The idea is that in these examples:
This was the most common use of
finally
in older versions of Java. In Java 7 a new construct, called "try with resources," was introduced that supplants thetry { ... } finally { ... }
in its most common uses:Another kind of example is with the synchronization tools between threads ("threads"). In the package
java.util.concurrent.locks
there are several kinds of locks ("locks") that are normally used withtry {...} finally {...}
:But it is worth emphasizing again the concept of postconditions. After all, the
try { ... } finally { ... }
is not specifically a "cleanup" mechanism but a general tool to facilitate the composition of correct programs. So it has other uses, even if they are much less common than these two.Other examples can be added. A frequent cause of programming errors is the early exit ("early return") of a function or method. Typical cases are something like this:
Assuming that we always need to call the method
cosaQueSiempreTieneQuePasar()
, this example has a bug: when itnoSéQué()
returns withtrue
we exit early and forget to callcosaQueSiempreTieneQuePasar()
. A solution in many cases is the following: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 withbreak
andcontinue
in repetition structures likefor (...) {...}
.Or rather, the exceptions, the
return
early, thebreak
and thecontinue
have something in common—early exit of a block of code—and thefinally
is a common solution to the problems that all of these cause.Apparently it's not such a bad practice since the
finally
will always run can be used for cleaning. I found a couple of examples on the net:Example 1
Example 2
Here a user says that in the following example
catch
he would not know what to do with the error so it would be better to add a cleanup routine.The block
catch
is only used to catch any exception that appears during the execution of the code. Since there is no blockcatch
, the exception will be thrown and handled by the client of the method where this block of code is located. If there is no handling of this exception, then the exception will jump to the highest level it can reach. If the highest level is thepublic static void main(String[] args)
application method and it is not handled there, then the application will show the exception that has been thrown and "terminate".It should be noted that the block
finally
is always executed, whether or not the exception was thrown up to the highest level of the application. There are cases where it doesn't runfinally
but they are external to this answer. you can see them hereUse
try-finally
when your code doesn't need to handle the exception because another level already exists where it will be handled. For example, in a web application where you have some X component that decorates the components that execute the requests and X already has a way of handling exceptions by default, which will automatically log them and show a "nice" message to the user ( I don't know which error message is actually pretty). An example of this example (forgive the redundancy) is the case of Spring MVC where you can use@ControllerAdvice
to handle exceptions at a general level. In this way, if your code throws an exception, it will not be handled by the code itself, but by the class decorated with this annotation.It is not a bad practice, it is a matter of order.
As other people already mentioned,
try
withfinally
is used to clean up in case an exception occurs, without catching that exception.As of Java 7 you have try with resources , there can already be even blocks that only include
try
:The
finally
is left over because the stream is going to close ending the block.It could be used in processes that, if they fail, do not need to be informed or alert the user. but it is a bad practice, at least you should record an exception log in the catch
The complete clause is: Try, Catch and Finally. It is possible that they did not use the error catch block because it was not necessary to make any kind of notification... However, you should add it to, in the future, better identify why and where the problem is occurring.
System.out.println("Salgo de la funcion Clase1.pepito()");