Is Try-Catch More or Less Expensive Than Try-With-Resources

Try-catch-finally and try-with-resources have essentially the same performance because under the covers they generate essentially the same bytecode.

However, your second version (try..catch..finally) is not quite formulated correctly as it could (in theory) lead to an undesirable NullPointerException when sc.close() is called. If the act of constructing a Scanner causes an exception to be thrown then sc will not be assigned and will be null.

You should construct the Scanner outside of the try..finally and change this:

Scanner sc = null;
try {
    sc = new Scanner(new File("file.txt"));
    ...

to:

Scanner sc = new Scanner(new File("file.txt"));
try {
    ...

Alternatively, you should check that sc != null in the finally clause before calling sc.close(). This won't be necessary if you create the scanner outside of the try..finally, so I would recommend you do that.

To do the same job as try-with-resources, you will also need to put a second try..catch around the sc.close() with an empty catch block, to ignore any exceptions thrown during close. If you do that, I suppose you don't need to worry so much about the null check.


It's apples and oranges. An ARM (automatic resource management, or try-with-resources) block does more than the old-fashioned try-catch-finally block that you show. That's because it generates the code to handle exceptions that are thrown in resource closure with the suppression mechanism. (A related answer discusses this in some detail.)

If you are writing new code, use an ARM block. It is easier to read, maintain, and it does more. Unless you are running in a tightly constrained environment (like a smart card), these advantages are likely to outweigh the cost of a few extra byte codes.


  1. try-catch is not the expensive part. Throwing the exception is (generating the stacktrace).
  2. "Expensive" above means "costs some microseconds".
  3. try-with-resources is just try-catch with proper code needed to reliably close the resource.
  4. Your measurement code cannot prove anything due to all the well-known pitfalls of trying to measure performance within an optimizing runtime such as HotSpot. You need to warm up, repeat the same many times, and much more.
  5. If your result is above 10 ms, then clearly you cannot have an issue with try-catch, which can altogether impose an overhead of several microseconds.