3

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)
    }

}
Suslik
  • 929
  • 8
  • 28
  • What do you want the code to do if, say, val < 1? – Steve Smith Jan 30 '19 at 16:20
  • What are you trying to achieve? Your code will only finish properly if you use "1" as parameter – RKrum Jan 30 '19 at 16:40
  • Anyway, you could do some reading on RuntimeExceptions here: https://stackoverflow.com/questions/22996407/java-throws-runtimeexception – RKrum Jan 30 '19 at 16:41
  • On a old slide I found this example, where one has to explain how the flow through the code looks like. There was also a note to use `throw NullPointerException, IllegalStateException' after the signature of the method. But why should I use it? I can understand, that a correct version would use multiple catch-blocks for handeling all exceptions. – Suslik Jan 30 '19 at 18:11
  • 1
    @Susliks - *"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. – Nicholas K Jan 30 '19 at 18:48

2 Answers2

1

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.

Nicholas K
  • 15,148
  • 7
  • 31
  • 57
1

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:

Rann Lifshitz
  • 4,040
  • 4
  • 22
  • 42