Using finally without a catch - java

I have a test I want to execute. No matter if it passes or throws an error I want to close a case it opened. I have at the top of the class String theCase = null;
Then in executeText() I set it once the case is open.
So I did this :
try {
executeTest(tContext);
} catch (Throwable t) {
throw t;
} finally {
if (theCase != null) {
closeCase(user, theCase);
}
}
I am wondering. Do I need the catch (Throwable t)? I still want the error to be thrown, but first I want it to close the case. If I don't catch it and throw it, will finally not throw it? Or will it not be caught and throw the exception and not execute the finally? I am a bit unclear about finally.

Do I need the catch (Throwable t)?
No you don't.
In fact, it is harmful, because if you catch and throw Throwable like that, then for some versions of Java you will need to declare the enclosing method as throws Throwable ... and so on. (That was address in Java 8, IIRC.)

Finally will be executed irrespective of whether an exception was thrown or not, or whether it was rethrown from a catch block.

Related

What is the purpose of throwing all caught exceptions?

I'm going through our code for our core programs to refactor and I encountered this weird try/catch block
try {
//Do some socket and network stuff
} catch (NoRouteToHostException e) {
throw e;
} catch (UnknownHostException e) {
throw e;
} catch (IOException e) {
throw e;
} finally {
//Does some counting stuff over here
}
Now I can't understand why on earth someone would do something like this, the people who wrote this code have left the company, but were indeed very skilled.
Is there a purpose to this try/catch block? Would it not be better to just throw these exceptions and do the finally things from where the method is called?
If you do literally nothing with the exception before you rethrow it, there is no point in catching it. Remove the catch block for that particular exception.
try doesn't need any catch blocks, provided there is a finally.
Note that catch (SomeException e) {} is doing something with the exception: it is swallowing it (which is likely not advisable anyway). As such, you cannot remove this without changing semantics.
The only exception (no pun intended) is if you don't want to catch a particular subclass of an otherwise-caught exception. For example:
try {
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
// Do something.
}
If you were to remove the catch/rethrow of FileNotFoundException, it would change the semantics because it would be handled by the more-general IOException. As written, a FNFE will "leap frog" the catch block for IOE.
(This is only very occasionally useful).
Either they didn't know they could write try-finally without catch or it's a legacy piece and it formerly performed something different for each catch block.
Otherwise, it makes no sense and it's identical to
try {
// Do some socket and network stuff
} finally {
// Does some counting stuff over here
}
Even skilled people tend to make mistakes, particularly when a deadline approaches.
If you throw every exception you catch, you will end up with an unhandled exception and your application will crash. At some point in your code, you will have to decide how you will deal with the error. If you are writing a GUI application this may be at the GUI layer, where you display an error message to your user. However, throwing all exceptions caught is no different to simply marking your method with throws IOException, ....
Also, since Java 7, you can use try-with-resources, for example:
try (Socket socket = serverSocket.accept()) {
socket.getInputStream() // whatever
} catch (IOException e) {
doSomething(e);
}
Note that you can still omit the catch block and simply pass the exception up to the enclosing scope.

Significance of finally block [duplicate]

This question already has answers here:
Why use finally instead of code after catch [duplicate]
(14 answers)
Closed 5 years ago.
What is the significance of the Finally block in a Try...[Catch]...Finally block?
Isn't this code
Resource r;
try{
r = new Resource();
r.methodThatThrowsException();
} catch (Exception e) {
e.printStackTrace()
} finally {
r.close()
}
equivalent to
Resource r;
try{
r = new Resource();
r.methodThatThrowsException();
} catch (Exception e) {
e.printStackTrace()
}
r.close()
? I would understand if they have the same scope, but the fact that I have to define Resource r outside the try block anyway to use it in the finally block means that I see no advantage to using a finally block.
Am I missing something? Is there a certain case that I haven't thought of that requires a Finally block?
In this case, they are equivalent since (a) the code catches any exception, including runtime exceptions that are thrown and (b) the catch block doesn't rethrow the exception, so the execution continues.
The finally block is generally used to ensure resource release in cases where either (a) or (b) don't hold. In newer Java implementations, wherever possible, you should use try-with-resources instead.
The two code snippets are different: the second one will not close if exception handling block ends in another exception.
Here is an illustration:
public static void one() throws Exception {
try {
System.out.println("One");
throw new Exception();
} catch (Exception e) {
System.out.println("Catch one");
if (2 != 3) throw new Exception(); // "if" silences compiler's check
} finally {
System.out.println("Finally one");
}
}
public static void two() throws Exception {
try {
System.out.println("Two");
throw new Exception();
} catch (Exception e) {
System.out.println("Catch two");
if (2 != 3) throw new Exception(); // "if" silences compiler's check
}
System.out.println("After two");
}
The call to one() prints Finally one, while After two never gets printed (demo 1).
The finally block becomes even more important when you catch specific exceptions (blindly catching Exception is nearly always a bad idea), because the try block may bypass your cleanup code by throwing an exception that you do not catch. Here is another illustration:
public static void error() throws Exception {
try {
System.out.println("Try");
throw new Error();
} catch (Exception e) {
System.out.println("Catch");
throw new Exception();
} finally {
System.out.println("Finally");
}
}
This code prints Try and Finally, without Catch in the middle, because Error is not caught in the catch block (demo 2).
It goes without saying that human readers of your program will have easier time locating you clean-up code if you place it in the finally block.
No, it is not equivalent. In the first snippet r.close() will be always called, while in the second snippet r.close() might not be called:
when the try block throws an Error (what might happen when you use assertions and an assertion fails)
when the exception handler throws another Exception
To ensure the resources are always released close() method should be called from finally blocks.

Will an assertion error be caught by in a catch block for java exception?

Code:-
try {
Assert.assertEquals("1", "2");
} catch (Exception e) {
System.out.println("I am in error block");
}
If the assert statements fails, I would like to capture the error in the catch block. I am trying with the above code and its not happening.
Will the assertion error be caught by in a catch block for java exception?
You have almost answered your own question. Your catch block will not catch the AssertionError that the Assert throws if it fails, because it is an Error (or, more specifically, it extends java.lang.Error). See the docs for more information on this. Your catch block only catches Throwable objects that extend java.lang.Exception
If you really want to catch it - you need to use
catch (AssertionError e) {
...
However, as others have mentioned, this is a very unusual way to use assertions - they should usually pass and if they fail it is very unusual for you to want to carry on the program execution. That's why the failure throws an Error rather than an Exception. You can read more about (not) catching Error in this question.
If you just want a test the variable value, it is preferred to use if ( variableName == "1")
NB if you are testing unit-test helper code, like a matcher, it might make sense to catch the AssertionError.
If you want to catch both Exception and Error instances use:
...
catch (Throwable t)
{
...
}
Since both Exception and Error extend Throwable.
Well, I believe you are using JUnit for writing your tests. In that case, you should not catch your Assert.assertEquals() because they should pass for normal test execution. If it throws any exception, it means that your code is not performing as it should.
If you want to catch the errors in that way you need something like the following:
if (num == 1 || num == 2) {
throw new Exception();
}
You could create your own exception class and pass in the message you want.

How can I catch all the exceptions that will be thrown through reading and writing a file?

In Java, is there any way to get(catch) all exceptions instead of catch the exception individually?
If you want, you can add throws clauses to your methods. Then you don't have to catch checked methods right away. That way, you can catch the exceptions later (perhaps at the same time as other exceptions).
The code looks like:
public void someMethode() throws SomeCheckedException {
// code
}
Then later you can deal with the exceptions if you don't wanna deal with them in that method.
To catch all exceptions some block of code may throw you can do: (This will also catch Exceptions you wrote yourself)
try {
// exceptional block of code ...
// ...
} catch (Exception e){
// Deal with e as you please.
//e may be any type of exception at all.
}
The reason that works is because Exception is the base class for all exceptions. Thus any exception that may get thrown is an Exception (Uppercase 'E').
If you want to handle your own exceptions first simply add a catch block before the generic Exception one.
try{
}catch(MyOwnException me){
}catch(Exception e){
}
While I agree it's not good style to catch a raw Exception, there are ways of handling exceptions which provide for superior logging, and the ability to handle the unexpected. Since you are in an exceptional state, you are probably more interested in getting good information than in response time, so instanceof performance shouldn't be a big hit.
try{
// IO code
} catch (Exception e){
if(e instanceof IOException){
// handle this exception type
} else if (e instanceof AnotherExceptionType){
//handle this one
} else {
// We didn't expect this one. What could it be? Let's log it, and let it bubble up the hierarchy.
throw e;
}
}
However, this doesn't take into consideration the fact that IO can also throw Errors. Errors are not Exceptions. Errors are a under a different inheritance hierarchy than Exceptions, though both share the base class Throwable. Since IO can throw Errors, you may want to go so far as to catch Throwable
try{
// IO code
} catch (Throwable t){
if(t instanceof Exception){
if(t instanceof IOException){
// handle this exception type
} else if (t instanceof AnotherExceptionType){
//handle this one
} else {
// We didn't expect this Exception. What could it be? Let's log it, and let it bubble up the hierarchy.
}
} else if (t instanceof Error){
if(t instanceof IOError){
// handle this Error
} else if (t instanceof AnotherError){
//handle different Error
} else {
// We didn't expect this Error. What could it be? Let's log it, and let it bubble up the hierarchy.
}
} else {
// This should never be reached, unless you have subclassed Throwable for your own purposes.
throw t;
}
}
Catch the base exception 'Exception'
try {
//some code
} catch (Exception e) {
//catches exception and all subclasses
}
You may catch multiple exceptions in single catch block.
try{
// somecode throwing multiple exceptions;
} catch (Exception1 | Exception2 | Exception3 exception){
// handle exception.
}
It is bad practice to catch Exception -- it's just too broad, and you may miss something like a NullPointerException in your own code.
For most file operations, IOException is the root exception. Better to catch that, instead.
Do you mean catch an Exception of any type that is thrown, as opposed to just specific Exceptions?
If so:
try {
//...file IO...
} catch(Exception e) {
//...do stuff with e, such as check its type or log it...
}
Yes there is.
try
{
//Read/write file
}catch(Exception ex)
{
//catches all exceptions extended from Exception (which is everything)
}

Exception thrown inside catch block - will it be caught again?

This may seem like a programming 101 question and I had thought I knew the answer but now find myself needing to double check. In this piece of code below, will the exception thrown in the first catch block then be caught by the general Exception catch block below?
try {
// Do something
} catch(IOException e) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}
I always thought the answer would be no, but now I have some odd behaviour that could be caused by this. The answer is probably the same for most languages but I'm working in Java.
No, since the new throw is not in the try block directly.
No. It's very easy to check.
public class Catch {
public static void main(String[] args) {
try {
throw new java.io.IOException();
} catch (java.io.IOException exc) {
System.err.println("In catch IOException: "+exc.getClass());
throw new RuntimeException();
} catch (Exception exc) {
System.err.println("In catch Exception: "+exc.getClass());
} finally {
System.err.println("In finally");
}
}
}
Should print:
In catch IOException: class java.io.IOException
In finally
Exception in thread "main" java.lang.RuntimeException
at Catch.main(Catch.java:8)
Technically that could have been a compiler bug, implementation dependent, unspecified behaviour, or something. However, the JLS is pretty well nailed down and the compilers are good enough for this sort of simple thing (generics corner case may be a different matter).
Also note, if you swap around the two catch blocks, it wont compile. The second catch would be completely unreachable.
Note the finally block always runs even if a catch block is executed (other than silly cases, such as infinite loops, attaching through the tools interface and killing the thread, rewriting bytecode, etc.).
The Java Language Specification says in section 14.19.1:
If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
If the run-time type of V is assignable to the Parameter of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed. If that block completes normally, then the try statement completes normally; if that block completes abruptly for any reason, then the try statement completes abruptly for the same reason.
Reference:
http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#24134
In other words, the first enclosing catch that can handle the exception does, and if an exception is thrown out of that catch, that's not in the scope of any other catch for the original try, so they will not try to handle it.
One related and confusing thing to know is that in a try-[catch]-finally structure, a finally block may throw an exception and if so, any exception thrown by the try or catch block is lost. That can be confusing the first time you see it.
If you want to throw an exception from the catch block you must inform your method/class/etc. that it needs to throw said exception. Like so:
public void doStuff() throws MyException {
try {
//Stuff
} catch(StuffException e) {
throw new MyException();
}
}
And now your compiler will not yell at you :)
No -- As Chris Jester-Young said, it will be thrown up to the next try-catch in the hierarchy.
As said above...
I would add that if you have trouble seeing what is going on, if you can't reproduce the issue in the debugger, you can add a trace before re-throwing the new exception (with the good old System.out.println at worse, with a good log system like log4j otherwise).
It won't be caught by the second catch block. Each Exception is caught only when inside a try block. You can nest tries though (not that it's a good idea generally):
try {
doSomething();
} catch (IOException) {
try {
doSomething();
} catch (IOException e) {
throw new ApplicationException("Failed twice at doSomething" +
e.toString());
}
} catch (Exception e) {
}
No, since the catches all refer to the same try block, so throwing from within a catch block would be caught by an enclosing try block (probably in the method that called this one)
Old post but "e" variable must be unique:
try {
// Do something
} catch(IOException ioE) {
throw new ApplicationException("Problem connecting to server");
} catch(Exception e) {
// Will the ApplicationException be caught here?
}

Categories

Resources