This question already has answers here:
Java Try Catch Finally blocks without Catch
(11 answers)
Returning from a finally block in Java
(6 answers)
Closed 6 years ago.
public class ExceptionTest {
public static void main(String[] args) {
ExceptionTest et = new ExceptionTest();
try {
et.testMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
public int testMethod() {
try {
throw new Exception();
}finally {
return 4;
}
}
The above code is working fine, but when I change return type of testMethod() to void and changing the line return 4; to System.out.println("some print msg"); is causing compilation problem.
Can anybody please give solution for why it is giving compilation error?
The problem is that a return statement inside a finally block will cause any exception that might be thrown in the try block to be discarded.
When you remove the return from the finally then what the code is doing is to throw a checked exception which requires that you throw Exception or you catch it and this is the reason why there's a compiler error.
Look at
https://www.owasp.org/index.php/Return_Inside_Finally_Block
Returning from a finally block in Java
Does finally always execute in Java?
The behaviour of return in finally is described in Java Language Specification and is well explained here http://thegreyblog.blogspot.it/2011/02/do-not-return-in-finally-block-return.html
This code works in Java 8:
public class ExceptionTest {
public ExceptionTest() {
}
public static void main(String[] args) {
ExceptionTest et = new ExceptionTest();
try {
et.testMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
public void testMethod() throws Exception {
try {
throw new Exception();
} finally {
//return 4;
System.out.println("hello finally");
}
}
}
The only compilation problem for me was the missing "throws Exception" in the method declaration.
This is the output:
hello finally
java.lang.Exception
at ExceptionTest.testMethod(ExceptionTest.java:17)
at ExceptionTest.main(ExceptionTest.java:9)
Related
Following is my code, when I am commenting statement-2 then it complies fines but when I uncomment it gives Compile Time Error "Unreachable Code".
I understand why I am getting error after uncommenting it, but my question is even if I comment it still the bad() is unreachable as I am throwing an exception is catch then why it is not giving error for it ?
class Varr
{
public static void main(String[] args) throws Exception
{
System.out.println("Main");
try {
good();
} catch (Exception e) {
System.out.println("Main catch");
//**Statement 1**
throw new RuntimeException("RE");
} finally {
System.out.println("Main Finally");
// **Statement 2**
throw new RuntimeException("RE2");
}
bad();
}
}
but my question is even if i comment it still the bad() is
unreachable as i am throwing an exception is catch then why it is not
giving error for it ?
Because the execution will not necessary enter in the catch statement.
Suppose that good() doesn't thrown any exception, so you don't enter in the catch and therefore bad() is then executed :
public static void main(String[] args) throws Exception
{
System.out.println("Main");
try {
good(); // doesn't throw an exception
} catch (Exception e) {
System.out.println("Main catch");
throw new RuntimeException("RE");
}
bad(); // execution goes from good() to here
}
Here's the code.
public class TestTest {
public static void main (String[] args) throws Exception {
try {
run();
} catch(Exception e) {
printSuppressedExceptions(e);
}
}
public static void printSuppressedExceptions(Throwable t) {
System.out.println(t);
System.out.println("suppressed exceptions: " + t.getSuppressed().length);
}
public static void run() throws Exception {
try(MyResource r = new MyResource("resource");) {
System.out.println("try");
System.getProperty("").length(); // throws illegalArgumentException
} catch(Exception e) {
printSuppressedExceptions(e);
throw e;
} finally {
new MyResource("finally").close();
}
}
}
class MyResource implements AutoCloseable {
private final String name;
public MyResource(String name) {
this.name = name;
}
#Override
public void close() throws Exception {
throw new Exception("exception" + " from " + this.name);
}
}
Since exception thrown from try block suppressed the exception from resource, I got "suppressed exceptions: 1" at first which was understandable. But when an exception was thrown from finally, it seemed like all suppressed exceptions disappeared because I got "java.lang.Exception: exception from finally" followed by "suppressed exceptions: 0" which I think it should be 1.
I browsed the Java tutorials and it definitely says
However, in this example, if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed.
From The try-with-resources Statement
How could it happen?
Here is code that does what you would expect:
public class TestTest {
public static void main (String[] args) throws Exception {
try {
run();
} catch(Exception e) {
printSuppressedExceptions(e);
}
}
public static void printSuppressedExceptions(Throwable t) {
System.out.println(t);
System.out.println("suppressed exceptions (" + t.getSuppressed().length + "):");
for (Throwable suppressed : t.getSuppressed()) {
System.out.println(" - " + suppressed);
}
}
public static void run() throws Exception {
Exception exceptionFromCatch = null;
try(MyResource r = new MyResource("resource");) {
System.out.println("try");
System.getProperty("").length(); // throws illegalArgumentException
} catch(Exception e) {
exceptionFromCatch = e;
printSuppressedExceptions(e);
throw e;
} finally {
try {
new MyResource("finally").close();
} catch (Exception e) {
if (exceptionFromCatch!=null) {
e.addSuppressed(exceptionFromCatch);
}
throw e;
}
}
}
}
class MyResource implements AutoCloseable {
private final String name;
public MyResource(String name) {
this.name = name;
}
#Override
public void close() throws Exception {
throw new Exception("exception" + " from " + this.name);
}
}
So lets go trough the try-with-resource part of your code (as introduced in JDK 1.7.0) and see what happens (see What is the Java 7 try-with-resources bytecode equivalent using try-catch-finally? for more details):
the try-with-resource block MyResource r = new MyResource("resource") is executed
the try block is executed and throws an IllegalArgumentException
the try-with-resource block calls close() for all resources (in your example only one)
close() throws an exception, but since the exception from the try block has priority the exception from thrown by close() is suppressed and added via addSuppressed(..)
So that part works like you expected from reading the tutorial.
And now the try-catch-finally part of your code (as in JDK 1.6 and earlier):
the try block is executed and throws an IllegalArgumentException
(the catch block behaves the same way as if there was no catch block)
the finally block is executed and throws an Exception
the exception from the finally block has priority and the one from the try block is suppressed
But this time the word suppressed used in the java tutorial does not stand for "suppressed and added to the actually thrown exception" but "suppressed and lost to nirvana". So it still behaves as in JDK 1.6 and earlier and does not make use of the newly introduced addSuppressed(..) getSuppressed() functionality. That's the reason it doesn't behave like you expected.
I would argue the behaviour you expected wouldn't be logical either. I would like it to behave like this:
...
} finally {
try {
new MyResource("finally").close();
} catch (Exception e) {
if (exceptionFromCatch!=null) {
exceptionFromCatch.addSuppressed(e);
} else {
throw e;
}
}
}
...
That would always give priority to the exception from the try block (as implemented with the new try-with-resource feature) and add the exception from the catch block as suppressed to the list. But that would break compatibility with JDK 1.6, so I guess that's the reason why it doesn't behave like that.
import java.io.*;
class West1 extends Exception {
private String msg;
public West1() {
}
public West1(String msg) {
super(msg);
this.msg=msg;
}
public West1(Throwable cause) {
super(cause);
}
public West1(String msg,Throwable cause) {
super(msg,cause);
this.msg=msg;
}
public String toString() {
return msg;
}
public String getMessage() {
return msg;
}
}
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
}catch(West1 ce) {
System.out.println(ce.getMessage());
//throw new NumberFormatException();
throw new FileNotFoundException();
}catch(FileNotFoundException fne) {
fne.printStackTrace();
}/*catch(NumberFormatException nfe) {
nfe.printStackTrace();
}*/
}
}
In the above code, NumberFormatException is thrown from catch block it compile and run successfully but when FileNotFoundException is thrown from catch block it will not compile. Following Errors are thrown:
West.java:40: error: exception FileNotFoundException is never thrown in body of
corresponding try statement
}catch(FileNotFoundException fne){
West.java:39: error: unreported exception FileNotFoundException; must be caught
or declared to be thrown
throw new FileNotFoundException();
So my question is what is reason behind this behaviour?
NumberFormatException is a RuntimeException, meaning that it's not required to be declared in all methods it may be thrown. This means that, unlike FileNotFoundException, the compiler can not know if it can get thrown in a block or not.
The title implies you are trying to catch multiple exceptions at once, and your code implies you understand that you can have multiple catch blocks for a single try block to catch different types of exceptions. Everything is good so far, but you seem to misunderstand exactly where the try-catch catches errors.
Here is you code. I removed the comments to make it more concise.
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
} catch(West1 ce) {
System.out.println(ce.getMessage());
throw new FileNotFoundException(); // <-- Must be caught
} catch(FileNotFoundException fne) { // <-- Never thrown
fne.printStackTrace();
}
}
}
The first compiler error is because the catch block that is for catching FileNotFoundException's try block never throws FileNotFoundException. The second compiler error is because FileNotFoundException is a checked exception. Because it is a checked exception your code must either
handle it (by catching it with try-catch)
let everyone know it could throw it (public static void main(String[] args) throws FileNotFoundException { ...).
From the context of your code, you seem to be going with the first option, handling it with try-catch, but you have the catch in the wrong place.
catch blocks don't catch exceptions, try blocks do. catch blocks specify what to do with the actual caught exception.
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
} catch(West1 ce) {
System.out.println(ce.getMessage());
try {
throw new FileNotFoundException();
} catch(FileNotFoundException fne) {
fne.printStackTrace();
}
}
}
}
Try that instead. Notice how you can have a try instead of a catch. This wouldn't matter if FileNotFoundException wasn't a checked exception.
For my final in Java we have a "exceptions" part on the test with try, catch, and finally calls. When I try to put the example code into Eclipse I get errors in the catch and throw new areas. All of the errors say "Can not be resolved to type".
How do I fix this so I can learn/review what the code is supposed to be doing?
Q4 Class
public static void main(String [] args)
{
Q4Exception q1 = new Q4Exception();
try{
q1.sampleMethod();
try{
q1.sampleMethod();
}
//This catch does not throw an error
catch(RuntimeException es)
{
System.out.println("A");
}
//This catch below throws the error of cannot be resolved to a type
catch(IOException es)
{
System.out.println("B");
}
//This catch does not throw an error
catch(Exception e)
{
System.out.println("C");
}
finally{
System.out.println("D");
}
}catch(Exception e)
{
System.out.println("E");
}
finally{
System.out.println("F");
}
}
Q4Exception Class
public void sampleMethod() throws Exception
{
try{
throw new IOException("H");
}
catch(IOException err)
{
System.out.println("I");
throw new RuntimeException("J");
}
catch(Exception e)
{
System.out.println(e.toString());
System.out.println("K");
throw new Exception(“L");
}
catch(Throwable t)
{
System.out.println("M");
}
finally{
System.out.println("N");
}
}
I think it's worth mentioning that in Eclipse, Ctrl+Shif+O does the job of resolving the imports for you.
Oh, guess I could answer my own question here.
Didn't know I had to import the IOException from java.io!
Easy to just use
import java.io.*
for the imports
I discovered I was using an old version of JWT , the issue is gone after using the a newer version of JWT dependency .
This question already has answers here:
Close resource quietly using try-with-resources
(4 answers)
Closed 1 year ago.
I was reading about the try-with-resource in JDK7 and while I was thinking of upgrading my application to run with JDK7 I faced this problem..
When using a BufferedReader for example the write throws IOException and the close throws IOException.. in the catch block I am concerned in the IOException thrown by the write.. but I wouldn't care much about the one thrown by the close..
Same problem with database connections.. and any other resource..
As an example I've created an auto closeable resource:
public class AutoCloseableExample implements AutoCloseable {
public AutoCloseableExample() throws IOException{
throw new IOException();
}
#Override
public void close() throws IOException {
throw new IOException("An Exception During Close");
}
}
Now when using it:
public class AutoCloseTest {
public static void main(String[] args) throws Exception {
try (AutoCloseableExample example = new AutoCloseableExample()) {
System.out.println(example);
throw new IOException("An Exception During Read");
} catch (Exception x) {
System.out.println(x.getMessage());
}
}
}
how can I distinguish between such exceptions without having to create wrappers for classes such as BufferedReader?
Most of cases I put the resource close in a try/catch inside the finally block without caring much about handling it.
Lets consider the class:
public class Resource implements AutoCloseable {
public Resource() throws Exception {
throw new Exception("Exception from constructor");
}
public void doSomething() throws Exception {
throw new Exception("Exception from method");
}
#Override
public void close() throws Exception {
throw new Exception("Exception from closeable");
}
}
and the try-with-resource block:
try(Resource r = new Resource()) {
r.doSomething();
} catch (Exception ex) {
ex.printStackTrace();
}
1. All 3 throw statements enabled.
Message "Exception from constructor" will printed and the exception thrown by constructor will be suppressed, that means you can't catch it.
2. The throw in constructor is removed.
Now the stack trace will print "Exception from method" and "Suppressed: Exception from closeable" below. Here you also can't catch the suppressed exception thrown by close method, but you will be nofitied about the suppressed exception.
3. Throws from constructor and method are removed.
As you have probably already guessed the "Exception from closeable" will be printed.
Important tip: In all of above situations you are actually catching all exceptions, no matter where they were throwed. So if you use try-with-resource block you don't need to wrap the block with another try-catch, the extra block is simply useless.
Hope it helps :)
I would suggest using a flag as in the following example:
static String getData() throws IOException {
boolean isTryCompleted = false;
String theData = null;
try (MyResource br = new MyResource();) {
theData = br.getData();
isTryCompleted = true;
} catch(IOException e) {
if (!isTryCompleted )
throw e;
// else it's a close exception and it can be ignored
}
return theData;
}
source:Close resource quietly using try-with-resources