简单 Java 程序在抛出异常时中断

Simple Java program breaks when throwing exception

我有一个抛出异常的简单程序,我理解我得到的输出,但不是我得到的异常。 这是代码:

//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");
  }

}

输出为:

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)

然后程序中断,但我不确定为什么。
有问题的行是 QE2 的构造函数中的行。
我假设,因为 QE2 是 RuntimeException 的子类,因此调用了 RuntimeException 的构造函数,所以程序中断。
是这种情况还是其他情况?

您的代码 output/behavior 没有什么意外。

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

您在 main 方法的 try 块中抛出了 QE2 类型的异常。但是,您实际上从未捕捉到这种类型的异常,因为您只捕捉到 QE1。结果,您最终进入 finally 块,该块打印 "finally".

如果你想捕获所有异常,那么你可以在 finally 块之前使用 catch (Exception e)