misty
misty

Reputation: 123

Simple Java program breaks when throwing exception

I have simple program with throwing exceptions, and I understand output I get, but not exception I get. Here is the code:

//Q1.java
import java.io.*;
import java.util.*;

public class Q1{
  public static void main(String args[]){
    Q1 q1=new Q1();
    Q2 q2=new Q2();
    try{
      System.out.println(q2.method(q1));
      System.out.println(q2.method(q2));
    }catch(QE1 e){
      System.out.println("exception 1");
    }finally{
      System.out.println("finally");
    }
  }

  Object method(Q1 q) throws QE1{ 
    if(q instanceof Q1){
      System.out.println("method");
    }
    else {
      throw new QE2();
    }
    return 1;
  }
}

class Q2 extends Q1{

  Object method(Q1 q) throws QE1{
    if(errorCheck()&& q instanceof Q2){
      throw new QE2("error 2");
    }else if(q instanceof Q2){
      throw new QE1();
    }else{
      return new String("abc");
    }
  }

  boolean errorCheck(){
    return true; 
  }

}

class QE1 extends Throwable{
  public QE1(){
    System.out.println("qe1 - 1");
  }
  public QE1(String s){
    super(s);
    System.out.println("qe1 - 2");
  }
}

class QE2 extends RuntimeException {

  public QE2(){
    System.out.println("qe2 - 1");
  }
  public QE2(String s){
    this();
    System.out.println("qe2 - 2");
  }

}

Output is:

abc
qe2 - 1
qe2 - 2
finally
QE2
    at Q2.method(Q1.java:33)
    at Q1.main(Q1.java:10)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)

and then program breaks, but I am not sure why.
Problematic line is the one in constructor of QE2.
I kind of assume that, because QE2 is subclass of RuntimeException and for that reason, constructor of RuntimeException is called, so program breaks.
Is this the case or something else?

Upvotes: 0

Views: 589

Answers (1)

Tim Biegeleisen
Tim Biegeleisen

Reputation: 520898

There is nothing unexpected about the output/behavior of your code.

public static void main(String args[]) {
    Q1 q1 = new Q1();
    Q2 q2 = new Q2();
    try {
        // this prints "abc" and no exception is thrown
        System.out.println(q2.method(q1));

        // this throws a new QE2(), which prints
        // this prints "qe2 - 1" followed by "qe2 - 2"
        System.out.println(q2.method(q2));
    } catch(QE1 e) {
        System.out.println("exception 1");
    } finally {
        // your code ends up here, which prints "finally"
        System.out.println("finally");
    }
}

You are throwing an exception of type QE2 in the try block of your main method. However, you never actually catch that type of exception, since you only catch QE1. As a result, you end up in the finally block, which prints "finally".

If you want to catch all exceptions, then you can use catch (Exception e) right before the finally block.

Upvotes: 1

Related Questions