I am aware that many questions about try-catch-finally blocks have been asked in this site. But I have a different doubt. I get different outputs when the code below is run multiple times.
I have a very simple class as follows:
Practice.java
public class Practice {
public static void main(String []args) {
System.out.println(getInteger());
}
public static int getInteger() {
try {
System.out.println("Try");
throwException();
return 1;
} catch(Exception e) {
System.out.println("Catch Exception");
e.printStackTrace();
return 2;
} finally {
System.out.println("Finally");
}
}
private static void throwException() throws Exception {
throw new Exception("my exception");
}
}
The output when I first run the code above is as follows:
Try
Catch Exception
Finally
2
java.lang.Exception: my exception
at exceptionHandling.Practice.throwException(Practice.java:22)
at exceptionHandling.Practice.getInteger(Practice.java:10)
at exceptionHandling.Practice.main(Practice.java:4)
A different output when I run the code again is given below:
Try
Catch Exception
java.lang.Exception: my exception
at exceptionHandling.Practice.throwException(Practice.java:22)
at exceptionHandling.Practice.getInteger(Practice.java:10)
at exceptionHandling.Practice.main(Practice.java:4)
Finally
2
Can somebody please explain such output?
You use different filehandles. Your output goes to System.out, e.printStackTrace(); writes to System.err which will flush on different times.
Related
try
{
someTask();
someTask2();
someTask3();
someTask4();
someTask5();
}
catch (Exception e)
{
// log the error
}
if one of my task fails, I want a log of what happened, but I want to continue running the rest of the tasks. I know I can surround each task method with its own try/catch, but is there a cleaner way so I don't have so many try/catch blocks?
The best way for this is for each of your methods to execute with a try/catch inside.
void someMethod(){
try{
//code of method 1
}catch(Exception e){
e.printstackTrace()
}
}
and then call them all without try/catch.
someTask();
someTask2();
someTask3();
someTask4();
someTask5();
Now if one fails, the other will just continue.
Assuming your task return void and take no parameters you could create a functional interface :
#FunctionalInterface
interface Task {
void perform() throws Exception;
}
then create a helper method that will handle logging and will take Task as parameter :
private static void invoke(Task task) {
try {
task.perform();
} catch (Exception e) {
// log here
}
}
And then use it :
class MyClass {
public static void main(String[] args) {
invoke(MyClass::someTask);
invoke(MyClass::someTask1);
}
private static void someTask() throws Exception {
System.out.println("Task 1");
}
private static void someTask1() throws Exception {
throw new Exception("Exception");
}
}
To run the rest of tasks, you have to put EVERY task in a separate ‘try’ block. It is a clean way to do so. Otherwise, how will you know which task failed and how will you debug it?
Also, It is considered as a good practice to put every expected error separately in catch block, starting from more specific and finishing with more general. So that you can immediately understand what what problem has happened and save time on debugging
try {
someTask1;
}catch (ClassNotFoundException e) {
// log the error
}catch (Exception e) {
// log the error
}
try {
someTask2;
}catch (ArithmeticException e) {
// log the error
}catch (ArrayIndexOutOfBoundsException e) {
// log the error
}catch (Exception e) {
// log the error
}
Maybe using a recursive method:
public void myMethod (int state){
try
{
switch(state) {
case 1:
state+=1;
someTask();
myMethod(state);
break;
case 2:
state+=1;
someTask2();
myMethod(state);
break;
case 3:
state+=1;
someTask3();
myMethod(state);
break;
default:
state=-1;
}
}
catch (Exception e)
{
// If some task had an exception, this catch call the next task, because the state variable incremented.
myMethod(state);
}
public static void main (String[] Args){
myMethod(1);
}
}
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.
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.
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");
}
}
}
I have wrote the code below which was taken from Java How to program 9th Edition - Paul and Michelle Harvey - The code works fine but the problem is that every time I execute it, it gives me uncertain results in which the exceptions are handled - e.g. please look at the output of the code snippet. can you please help me understand why this behavior is occurring ?
public class Test {
public static void main(String[] args) {
try {
// call method throwException
throwException();
}// end try
catch (Exception e) {
System.out.println("Exception handled in main");
}// end catch
// call method doesNotThrowException
doesNotThrowException();
}
private static void throwException() throws Exception {
try {
System.out.println("Method throwException.");
throw new Exception(); // generate exception
}
catch (Exception exception) {
System.err.println("Exception handled in method throwException");
throw exception;
}
// executes regardless of what occurs in try ... catch block
finally {
System.err.println("Finally executed in throwException.");
}
}// end of method throwException
private static void doesNotThrowException() {
try {
System.out.println("Method doesNotThrowException.");
}
// catch does not execute as the method does not throw any exceptions
catch (Exception exception) {
System.err.println(exception);
}// end catch
// executes regardless of what occurs in try ... catch block
finally {
System.err.println("Finally executed in doesNotThrowException");
}
}// end of deosNotThrowException
}//end Test Class
OUTPUTS:
1)
Method throwException.
Exception handled in method throwException
Finally executed in throwException.
Finally executed in doesNotThrowException
Exception handled in main
Method doesNotThrowException.
2)
Exception handled in method throwException
Finally executed in throwException.Method throwException.
Finally executed in doesNotThrowException
Exception handled in main
Method doesNotThrowException.
Different outputs on different runs are because of you're using 2 different output streams: out and err. It's up to the OS to flush such I/O streams and it does so in different ways on each run depending on other factors that have nothing to do with your program. The only thing the OS guarantees is that the order for out and the order for err are preserved, but not the order between them.