In a finally block, can I tell what exception has been thrown?
I understand, that we can verify in a finally block if an exception had been thrown.
I can't envision a situation in which this would ever a sensible thing to do, but you can try something like this:
class Main {
public static void throwsException() throws Exception {
throw new Exception();
}
public static void main(String[] args) {
Exception caughtException = null;
try {
throwsException();
}
catch (Exception e) {
caughtException = e;
e.printStackTrace();
}
finally {
System.out.println(caughtException);
}
}
}
catch block and finally are 2 different scopes . The exception caught in the catch block is not visible to finally block. You can use the Alexander answer to print the exception in the finally block.
Related
Is it any possible way there to write catch block inside a method and call it from finally when an exception occured in try block
Ex:
try
{
int a=0,b=0;
a=b/0;
}
finally
{
callExceptions();
}
}
public static void callExceptions()
{
catch(Exception e)
{
System.out.println(e);
}
}
catch block must follow a try block. It can't stand alone.
And finally block are made to be after the catch.
You wrote an alone catch inside a finally. That doesn't make sense.
The easiest solution is to pass the exception to the method as a parameter:
public static myMethod() {
try
{
int a=0,b=0;
a=b/0;
}
catch (Exception e)
{
callExceptions(e);
}
finally
{
// do what ever you want or remove this block
}
}
public static void callExceptions(Exception e)
{
System.out.println(e);
}
Ways to uses try/catch/finally
1.- when you want to try to use some method, if everything goes well, will continue else one exception will be thrown on catch block.
try {
// some method or logic that might throw some exception.
} catch (ExceptionType name) {
// catch the exception that was thrown.
}
2.- It's the same the first but adding finally block means that the finally block will always be executed independently if some unexpected exception occurs.
try {
// some method or logic that might throw some exception.
} catch (ExceptionType name) {
// catch the exception that was thrown.
} finally {
// some logic after try or catch blocks.
}
3.- try and finally blocks are used to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. For example:
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
Referencias Official documentation JAVA for try/catch/finally blocks
On your case:
public static myMethod() {
try {
int a=0,b=0;
a=b/0;
} catch (Exception e) {
callException(e);
}
}
public static void callException(Exception e) {
System.out.println(e);
}
This was too long for a comment so sorry it's not a direct answer to your question (as others have pointed out, that's not possible). Assuming what you're trying to do is define a common way to handle your exception logic in one place, Callable might be a way to go. Something like the following might suffice... Although I'm not going to comment on whether any of it is a good idea...
static E callAndHandle(final Callable<E> callable) {
try {
return callable.call();
} catch (final Exception ex) {
System.out.println(ex);
return null;
}
}
static void tryIt() {
final String result = callAndHandle(() -> {
// Thing which might throw an Exception
return "ok";
});
// result == null => there was an error here...
}
Unfortunately Runnable doesn't declare any Exception in the signature, so if you know it always needs to be void and you don't like the return null; or similar hacks, you'd have to define your own interface to pass in.
class TestExceptions {
public static void main(String[] args) throws Exception {
try {
System.out.println("try");
throw new Exception();
} catch(Exception e) {
System.out.println("catch");
throw new RuntimeException();
} finally {
System.out.println("finally");
}
}
}
Following are the outputs when I try to run the code in eclipse multiple times. I believed so far that whenever the last line of the code from either try/catch block is about to be executed (which could be return or throws new Exception() type of stmt), finally block will be executed, but here the output different every time? Can anyone clarify if my assumption is right or wrong?
try
catch
Exception in thread "main" finally
java.lang.RuntimeException
at TestExceptions.main(TestExceptions.java:9)
Exception in thread "main" try
catch
java.lang.RuntimeException
at TestExceptions.main(TestExceptions.java:9)
finally
This is clearly because eclipse is printing the error stream and output stream without proper synchronization in console. Lot of people have seen issues because of this.
Execute the program in a command prompt and you will see proper output every time.
while agreeing with #Codebender, you can replace all the thows exception and replace them with printStackTrace(); then the exceptions and out will be printed in syn.
EG:
public static void main(String[] args) throws Exception {
try {
System.out.println("try");
throw new Exception();
} catch(Exception e) {
System.out.println("catch");
e.printStackTrace();
} finally {
System.out.println("finally");
}
}
}
public class SampleCloseable implements AutoCloseable {
private String name;
public SampleCloseable(String name){
this.name = name;
}
#Override
public void close() throws Exception {
System.out.println("closing: " + this.name);
}
}
and the main class
public class Main{
public static void main(String args[]) {
try(SampleCloseable sampleCloseable = new SampleCloseable("test1")){
System.out.println("im in a try block");
} catch (IOException e) {
System.out.println("IOException is never thrown");
} catch (Exception e) {
} finally{
System.out.println("finally");
}
}
}
But when i removed the throws exception on close() method inside SampleCloseable
i am getting a compiler error saying that IOException is never thrown in the corresponding try block.
Because you're throwing a generic Exception. Since an IOException inherits from Exception, it might be thrown by the close() method. The caller doesn't know that it doesn't actually get thrown. It only sees the method signature that says that it could.
In fact, the close() method is free to throw any Exception of any kind. Of course that's bad practice, you should specify what specific Exceptions you're throwing.
Your confusion may that around the fact the in Java 7, the exception that is [declared to be] thrown from the close method is thrown inside the try block, so your catch block has to catch it as well.
Your close method is declared to throw an Exception, so your catch blocks have to catch that, or the method has to be declared to throw Exception.
And since IOException is a subclass of Exception, you are of course allowed to try and catch that as well, as long as your also catch/declare Exception itself.
See JLS 14.20.3.2:
The meaning of an extended try-with-resources statement [...] is given
by the following translation to a basic try-with-resources statement
(ยง14.20.3.1) nested inside a try-catch or try-finally or
try-catch-finally statement.
Your code is effectively translated to the below. Although a bit longish, it should be clear from the below what's happening in your code.
public static void main(String args[]) {
try {
Throwable primaryEx = null ;
SampleCloseable sampleCloseable = new SampleCloseable("test1")
try {
System.out.println("im in a try block");
} catch (Throwable t) {
primaryEx = t;
throw t;
} finally {
if (sampleCloseable != null) {
if (primaryEx != null) {
try {
sampleCloseable.close();
} catch (Throwable suppressedExc) {
primaryEx.addSuppressed(suppressedExc);
}
} else {
sampleCloseable.close();
}
}
} catch (IOException e) {
System.out.println("IOException is never thrown");
} catch (Exception e) {
} finally{
System.out.println("finally");
}
}
The main class:
class IO
{
static void m() throws Exception
{
try
{
throw new Exception();
} finally{
System.out.println("finally");
}
}
public static void main(String [] args)
{
try {
m();
} catch (Exception ex) {
System.out.println("catch");
}
System.out.println("finish");
}
}
Output:
finally
catch
finish
That behavior is unclear for me. Clause 11.3 of JLS 8 says:
If no catch clause that can handle an exception can be found, then the
current thread (the thread that encountered the exception) is
terminated. Before termination, all finally clauses are executed and
the uncaught exception is handled according to the following rules:
If the current thread has an uncaught exception handler set, then that
handler is executed.
Otherwise, the method uncaughtException is invoked for the ThreadGroup that is the parent > of the current thread. If the ThreadGroup and its parent ThreadGroups do not override
uncaughtException, then the default handler's uncaughtException method is invoked.
I expected that the output will be finally only because current thread is terminated. I haven't produced any other threads, since the output must be finally, but it is not true. Help me to understand, please.
If no catch clause that can handle an exception can be found, [...]
But you do have a catch clause that can handle the exception. Your m method will complete abruptly as a result of the exception being thrown. The exception will be caught and handled inside your main method which will then complete normally along with the main thread.
It might be easier to look at it like this, by replacing the function with the code from it.
class IO
{
public static void main(String [] args)
{
try { //4 Now goes to the outer try
try //2 Checks this try for the catch, but doesn't find it
{
throw new Exception(); //1 Hits the exception
} finally{ //3 Executes this because there is no catch for this try
System.out.println("finally");
}
} catch (Exception ex) { //5 Finds the catch
System.out.println("catch");
}
//6 Continues as if nothing happened
System.out.println("finish");
}
}
The following is the flow:
class IO
{
static void m() throws Exception
{
try
{ //2
throw new Exception();
} finally{
//3
System.out.println("finally");
}
}
public static void main(String [] args)
{
try {
m();//1 method called
} catch (Exception ex) {
//4 the control returns
System.out.println("catch");
}
//5
System.out.println("finish");
}
}
The thread is only terminated if the exception is not handled.
In Java, if a general exception is caught and rethrown, will outer methods still be able to catch specific exceptions?
In other words, can I do this:
try {
try {
//...
} catch (Exception e) {
//...
throw e;
}
} catch (SpecificException e) {
//...
}
re-throwing an exception does not change anything about it (it's still the same object originally thrown).
While jtahlborn answer is correct, there is one more appreciation: the compiler will see that you are throwing an exception of the generic type (even if at runtime it can be only of the specific class) and will force you to declare the generic exception in the method header.
private void test() throws FileNotFoundException {
try {
throw new FileNotFoundException("Es una exception");
} catch (IOException e) {
throw e; <-- Error because the method only throws
FileNotFoundException, not IOException
}
}
e is indeed FileNotFoundException, but as it is declared as IOException the compiler works with the broader class. What you can do is "cast" the exception.
throw (FileNotFoundException) e;
Eclipse marks the "throw e" in the inner catch as an unhandled exception, BUT it does catch the exception because when I run this it prints "It worked!". Thanks #jtahlborn. Unfortunately this means that there will still need to be an unnecessary try/catch block somewhere.
public class Tester {
public static void main(String[] args) {
try {
try {
throw new SpecificException("Test!");
} catch (Exception e) {
throw e;
}
} catch (SpecificException e) {
System.out.println("It worked!");
}
}
}