Java Throw-Catch Exception Confusion -1示例

时间:2014-09-29 04:15:18

标签: java exception scjp

我知道输出是什么。但问题是这个问题的解释是什么。

 public class LongExp{
  LongExp() throws Exception{
    LongExp.start();
  }
  public static void start()throws RuntimeException{
    throw new IllegalMonitorStateException();
  }
  public static void main(String args[]) throws Throwable{
    try{
      try{
        try{
          new LongExp();
        } catch(Throwable t){

          System.out.println("catch(Throwable t) 1" );
          throw t;
        }
      }catch(Throwable t){
          System.out.println("catch(Throwable t) 2" );
        if (t instanceof IllegalMonitorStateException){
             System.out.println("(t instanceof IllegalMonitorStateException)" );
          throw (RuntimeException)t;
        }else{
             System.out.println("else (t instanceof IllegalMonitorStateException)" );
          throw (IllegalMonitorStateException)t;
        }
      }
    }catch(IllegalMonitorStateException e){

      System.out.println("a" );
    }catch(RuntimeException e){

      System.out.println("b" );
    }catch(Exception e){
      System.out.println("c" );
    }catch(Throwable e){
      System.out.println("d" );
    }
  }
}

这是输出

catch(Throwable t) 1
catch(Throwable t) 2
(t instanceof IllegalMonitorStateException)
a

我解释了类型转换传播的内容, 它只是引用的更改,而不是该异常对象的实例类型。 这就是为什么最后它捕获了IllegalMonitorStateException。

我说错了吗?

编辑:拼写错误;

2 个答案:

答案 0 :(得分:1)

是的,它是运行时多态,你可以将子类的对象分配给父类引用类型。

在这里,您将IllegalMonitorStateException分配给不同的父类(Throwable,RuntimeException),其中包含IllegalMonitorStateException(子类)的实例。

The reason why you have got the IllegalMonitorStateException at the end is,it was the originally propagated object,and according to the exception handling rule,it will be caught by most specific catch block first than generic one

答案 1 :(得分:0)

是的,回答你的问题。

而且,为什么

因为我们总是可以将您案例中的子类引用IllegalMonitorStateException分配给父类。此外,当我们重新抛出异常时,请说E1 - 即使它被更高层次结构中的catch块捕获,也会预先知道有关此E1的所有内容。

您可以通过在外部catch块中打印堆栈跟踪来验证这一点。例如,

class Exception1 {

  Exception1() throws Exception{
    Exception1.start();
  }
  public static void start()throws RuntimeException{
    throw new IllegalMonitorStateException();
  }
  public static void main(String args[]) throws Throwable{
    try{
      try{
        try{
          new Exception1();
        } catch(Throwable t){
          t.printStackTrace();
          throw t;
        }
      } catch(Throwable t){
          t.printStackTrace();
          throw t;
       }
    } catch(IllegalMonitorStateException e){
        e.printStackTrace();
    }
  }
}

所有三个堆栈都将打印相同的描述。