exception-handling method exit without finishing - java

I am learning about exception handling and now I have a question.
I think the result of this code is 345,however,I don't know why the result is 35.
Shouldn't it run the code System.out.println(4) even though there is an exception happened?
public class Six {
public static void main(String[] args) {
try {
method1();
} catch(Exception e) {
System.out.println(5);
}
}
static void method1() {
try {
method2();
System.out.println(1);
} catch(ArithmeticException e) {
System.out.println(2);
} finally {
System.out.println(3);
}
System.out.println(4);
}
static void method2() {
throw new NullPointerException();
}
}

In method2() a NullPointerException is thrown whereas in method1() you only catch ArithmethicException which is a different Exception. In this case the the catch block of method1() is not processed. Only the finally block will be executed and then the method exits and the exception is re-thrown to the calling method (main())

No, 4 is not printed because the NullPointerException is still active, it was not caught at that point. The finally block (where 3 is printed) is guaranteed to be executed so you can do cleanup there, but it does not 'stop' the exception.

Related

Why would Java skip lines of code after method failure?

I've seen this behavior a few times lately. In the code below, why would execution jump to the finally block immediately after executing method2? I know method2 failed in some way, but I do know that neither method3 nor method4 are executed, instead jumping to method 5 in the finally block
try {
method1();
method2(); // fails
method3(); // not executed
} catch(Exception e) {
method4(); // not executed
} finally {
method5();
}
Hopefully you're clear on why method3() is not executing.
A possible reason that method4() would not execute is that method is throwing a Throwable that is not a subclass of Exception - most likely some kind of Error.
It is because the exception being thrown is not being caught by the type "Exception"
For example, an out of memory error.
public static void main(String[] args) {
try {
method1();
method2(); // fails
method3(); // not executed
} catch(Exception e) {
method4(); // not executed
} finally {
method5();
}
}
private static void method5() {
System.out.println("Done");
}
private static void method4() {
System.out.println("Hit");
}
private static void method3() {
}
private static void method2() {
throw new OutOfMemoryError();
}
private static void method1() {
}
You can catch error types by try {} catch (Throwable t) { }

How to handle a runtime error with throws

In the following code snippet, there are cases where the processes cannot handle NullPointerException and IllegalStateException. Namely in the case where I have the input values val=-4 or val=-2.
I read that adding throws after methods' signatures would help. But the code still aborts if I pass the mentioned values over.
public class Test extends Throwable{
public static void processA(int val ) throws NullPointerException, IllegalStateException{
try{
System.out.println("1");
processB(val);
}catch(ArithmeticException e){
System.out.println("2");
}
System.out.println("3");
}
public static void processB(int val) throws NullPointerException, IllegalStateException{
try{
System.out.println("4");
processC(val);
}catch(NullPointerException e){
System.out.println("5");
processC(val+4);
}finally{
System.out.println("6");
}
System.out.println("7");
}
public static void processC(int val)throws NullPointerException, IllegalStateException, ArithmeticException{
System.out.println("8");
if(val<1) throw new NullPointerException();
if(val==1) throw new ArithmeticException();
if(val>1) throw new IllegalStateException();
System.out.println("9");
}
public static void main(String[] args) throws Exception {
processA(1); //processA(-2) or processA(-4)
}
}
It breaks because you are not handling the scenario when a NullPointerException or IllegalStateException is thrown to processA(...). You only handle an ArithmeticException.
Add the following to your code, thereby if any of the three exceptions are thrown, it is handled by method processA.
public static void processA(int val) throws NullPointerException, IllegalStateException {
try {
System.out.println("1");
processB(val);
} catch (ArithmeticException e) {
System.out.println("11");
} catch (NullPointerException e) {
System.out.println("12");
} catch (IllegalStateException e) {
System.out.println("13");
}
System.out.println("3");
}
If you want the caller to handle them then you need to do the same from the caller method. For eg :
public static void main(String[] args) {
try {
processA(12);
} catch (ArithmeticException | NullPointerException | IllegalStateException e) {
// do something here
}
}
To answer your question in the comments: "But why should I use it?"
This will indicate that the caller will need to handle the exception thrown by that method. Now the caller can handle it via a try-catch block or it can re-throw the exception to its caller. The compiler would also give you an error saying that the exception should be handled but this would happen only for checked exceptions. The ones you are throwing are unchecked exceptions. Which means in your case you can pretty much ignore them from the method declaration.
I would suggest you also consider using Thread.UncaughtExceptionHandler in order to make sure you properly handle exceptions which were not properly caught.
Missing out on exception handling is a very common occurrence and can be easily avoided using this API.
References:
How to catch an exception from a thread
Oracle official API
UncaughtExceptionHandler as a best practice

Is return statement optional in a method that has return type not void, but throws an Exception?

Here I have a method that is expected to return a boolean :
static boolean display()
{
}
The compilation fails as This method must return a result of type boolean.
However, if the method is modified as below:
static boolean display()
{
try{
throw new ArithmeticException();
}
catch(ArithmeticException e)
{
throw e;
}
finally
{
System.out.println(finally);
}
}
Why does not the compilation fail anymore even though I have not added any return statement.
If in the catch block I do not include a throw statement, the compilation fails again with the previous reason.
The Java compiler does a (limited) flow analysis and when it can determine that all flows of control lead to an exception you don't need a return.
To understand try putting return true; at the end of the method. Then you should get a error calling unreachable statement.
This happens because your method always throwing an exception. So at the end you don't need to return a value, because it already throwing the exception before that and ends the method
You: Why does not the compilation fail anymore even though I have not added any return statement?
Answer: When you explicitly throw an exception in try block, and again
in the catch block you explicitly throw an exception, the compiler
does not give an error because you are throwing an exception
explicitly using the throw keyword, which terminates abruptly the
normal flow of code and stops the execution of all the subsequent code
in display method and control gets directly transfer to the calling
method
public class StackOverFlowReturn {
public static void main(String[] args) {
try {
System.out.println(display());
} catch (Exception ae) {
System.out.println("Arithmetic Exception");
}
}
static boolean display() {
try {
throw new ArithmeticException();
} catch (ArithmeticException e) {
throw e;
} finally {
System.out.println("finally");
}
}
}
Output:
finally
Arithmetic Exception
In catch block if you code return instead of explicit throw of
exception then
public class StackOverFlowReturn {
public static void main(String[] args) {
try {
System.out.println(display());
} catch (Exception ae) {
System.out.println("Arithmetic Exception");
}
}
static boolean display() {
try {
throw new ArithmeticException();
} catch (ArithmeticException e) {
return true;
} finally {
System.out.println("finally");
}
}
}
Output:
finally
true
You: If in the catch block I do not include a throw statement, the compilation fails again with the previous reason.
Answer: When you explicitly throw an exception in try block, then it
is not necessary to have an explicit throw in catch block. You can
code as follows:
public class StackOverFlowReturn {
public static void main(String[] args) {
System.out.println(display());
}
static boolean display() {
try {
throw new ArithmeticException();
} catch (ArithmeticException e) {
System.out.println("Arithmetic Exception");
} finally {
System.out.println("finally");
}
return true;
}
}
Output:
Arithmetic Exception
finally
true

java.lang.NullPointerException and return code

I'm running some java binary from bash like:
run_me.sh
$JAVA_HOME/bin/java -Djava.library.path=path1/libs/opencv/lib -jar path2/bin/application.jar
echo "Exit code: "$?
but inside application I get java.lang.NullPointerException, howewer return code is 0, but I need some non zero exit code to understand from bash that application failed.
What is the proper way to handle such cases?
Update:
Here is an exxample of 'nested' try catch blocks, when I throw exception in inner_package_class return code is 0. So what is the proper way to get exception from inner_package_class.method1()?
public static void main(String[] args) {
try {
inner_package_class.method1();
System.out.printf("After inner method!\n");
} catch (Throwable t) {
System.exit(1);
}
}
public class inner_package_class {
public static void method1() {
System.out.printf("From inner method!\n");
try
{
throw new Exception("Some exception 2.");
} catch (Throwable t) {
}
}
}
Update 1:
This work as expected (return non zero exit code).
public class inner_package_class {
public static void method1() throws Exception {
System.out.printf("From inner method!\n");
throw new Exception("Some exception 2.");
}
}
You can add a try-catch-block around your main method and use
System.exit(1)
when you catch a Throwable
public static void main(String[] args) {
try {
... // your original code
} catch (Throwable t) {
// log the exception
t.printStacktrace(); // or use your logging framework
System.exit(1);
}
}
the return code is set by the exit method of System: by the way if, for instance, You want to return -1 in case of exception you can do as follow: in Your Main class you have to catch all throwable (so you will handle all possible case). here is an example
public static void main(String[] args) {
try { YOUR CODE
} catch(throwable t){
System.exit(-1);
}
System.exit(0);
}
the code show You how return -1 in case of exception and 0 in case of success.

Invorking fillInStackTrace method after invoked printStackTrace method

Blow is a example copied from Think in Java 4 edition
public class Rethrowing {
public static void f() throws Exception {
System.out.println("originating the exception in f()");
throw new Exception("thrown from f()");
}
public static void h() throws Exception {
try {
f();
} catch (Exception e) {
System.out.println("Inside h(),e.printStackTrace()");
e.printStackTrace(System.out); //first print line throw (Exception) e.fillInStackTrace();
}
}
public static void main(String[] args) {
try {
h();
} catch (Exception e) {
System.out.println("main: printStackTrace()");
e.printStackTrace(System.out);
}
}
}
Output:
originating the exception in f()
Inside h(),e.printStackTrace()
java.lang.Exception: thrown from f()
at Rethrowing.f(Rethrowing.java:20)
at Rethrowing.h(Rethrowing.java:25)
at Rethrowing.main(Rethrowing.java:35)
main: printStackTrace()
java.lang.Exception: thrown from f()
at Rethrowing.f(Rethrowing.java:20)
at Rethrowing.h(Rethrowing.java:25)
at Rethrowing.main(Rethrowing.java:35)
When comment //first print line
Output:
originating the exception in f()
Inside h(),e.printStackTrace()
main: printStackTrace()
java.lang.Exception: thrown from f()
at Rethrowing.h(Rethrowing.java:29)
at Rethrowing.main(Rethrowing.java:35)
My question is why i first invoke e.printStackTrace(printOut out ) method before the fillInStackTrace mehod, and then the fillInStackTrace seems not available. Any one can do me a faver, thanks in advance.
user917879, When you call e.fillInStackTrace(); it resets the StackTrace. So, to print the current StackTrace - before it is get reset - you need to invoke the e.printStackTrace(printOut out ) first.

Categories