RT..代码如下:代码一:
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 g() throws Throwable {
try {
f();
}catch(Exception e) {
System.err.println("Inside g(), e.printStackTrace()");
e.printStackTrace();
throw e; // 17
//throw e.fillInStackTrace(); // 18
}
}
public static void main(String[] args) throws Throwable {
try {
g();
}catch(Exception e) {
System.out.println("Caught in main(), e.printStackTrace()");
e.printStackTrace();
}
}
}
代码二:
public class FullConstructors {
public static void f() throws MyException {
System.out.println("Throwing MyException from f()");
throw new MyException();
}
public static void main(String[] args) {
try{
f();
}catch(MyException e) {
e.printStackTrace();
}
}
}
如上. 在代码一中main()方法那行如果去掉 throws Throwable 编译时就会出错:
Rethrowing.java:28: unreported exception java.lang.Throwable; must be caught or
declared to be thrown
代码二的main()方法里没有throws声明却不会.请问为什么代码一中一定要throws声明..?谢谢.

解决方案 »

  1.   

    代码一:因为你只是throw了异常并没有catch它; g()抛出了throwable可是如果main也没有抛或者没有catch,那么throwable就没有程序来处理了,所以main又把异常抛给了上一层,(具体是谁处理我也不知道了,希望有人解答)代码二:main方法处理了来自f()方法中抛出的异常
      

  2.   

    楼上说的正确呵呵调用抛出异常的方法 要么就在方法定义处throws 异常(要求这个异常是或者能包含抛出的异常,不推荐Exception 或者 Throwable 这些基类),要么就在方法调用处try catch 一把 catch的异常依然得遵守上述规则 但是推荐使用本身抛出的异常
      

  3.   

    不解. 我g()方法和main()方法里都有catch处理啊. 为什么gifted1982兄会说只是throw了异常并没有catch它...?
      

  4.   

    楼主对于代码中的throw和方法声明中的throws的理解有错误public static void g() throws Throwable 
    这一行
    表明g()会抛出一个Throwable异常而g()中的catch(Exception e)中的Exception e异常不是g()自己抛出的,而是f()抛出的
    但是,g()也抛出了Exception异常,是因为g()在处理f()抛出的Exception异常的时候也抛出了Exception异常,如楼主代码"//17"处....那么g()实际上抛出了Throwable和Exception类型的两个异常
    main()中仅仅catch了Exception异常而没有catch  Throwable异常或者再次将Throwable异常抛出....所以有错误产生
      

  5.   

    楼上正确。Throwable是Exception的父类,因为g()被声明抛出Throwable,而你在main()中只处理了Exception异常,也就是说,只做了部分处理,而没有处理所有情况。改成:try {
      g();
    } catch(Throwable e) {
      //....
    }或者:try {
      g();
    } catch(Exception e) {
      //...
    } catch(Throwable e) {
      //....
    }均可。
      

  6.   

    1。 public static void main(String[] args) throws Throwable {
    try {
    g();
    }catch(Exception e) {
    System.out.println("Caught in main(), e.printStackTrace()");
    e.printStackTrace();
    }
    }
    中的throws Throwable 去掉应该就可以了,没有抛出新的exception
      

  7.   

    也可以改成这样的:
    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 g() throws Exception {
    try {
    f();
    }catch(Exception e) {
    System.err.println("Inside g(), e.printStackTrace()");
    e.printStackTrace();
    throw e; // 17
    //throw e.fillInStackTrace(); // 18
    }
    }
    public static void main(String[] args) {
    try {
    g();
    }catch(Exception e) {
    System.out.println("Caught in main(), e.printStackTrace()");
    e.printStackTrace();
    }
    }
    }
      

  8.   

    回liang8305兄,Dan1980兄.
    public static void g() throws Throwable 这个虽然有声明g()方法可能会抛出Throwable异常,但是实际上在g()方法里并没有抛出Throwable异常,而只是抛出了Exception异常. 我不能理解的是为什么g()也会抛出Throwable异常. 异常不是类似这样throw new Exception("thrown from f()"); 才会抛出吗..?
      

  9.   

    代码改成如下,编译通过可执行.
    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 g() throws Throwable {
    try {
    f();
    }catch(Exception e) {
    System.err.println("Inside g(), e.printStackTrace()");
    e.printStackTrace();
    throw e; // 17
    //throw e.fillInStackTrace(); // 18
    }
    }
    public static void main(String[] args) {
    try {
    g();
    }catch(Exception e) {
    System.out.println("Caught in main(), e.printStackTrace()");
    e.printStackTrace();
    }catch(Throwable t) {
    System.out.println("测试捕捉Throwable异常.");
    }
    }
    }但输出并没有"测试捕捉Throwable异常."这句, 是没有捕捉到Throwable异常..? 还是g()方法跟本没有抛出Throwable异常 ...?
      

  10.   

    回楼主:声明异常和实际抛出异常是两码事,你可以对一个方法声明抛出N多个异常却不抛出任何实际的异常,而调用时都必须全部捕获。比如下面这个方法没有抛出任何异常:void f() throws Exception {
      //没有抛出任何异常
    }但是由于它声明了一个Exception异常,所以在调用f()的时候,必须捕获Exception。
      

  11.   

    谢谢Dan1980兄. 已经有点了解了..但在上面我修改后的代码中,捕捉不到Throwable异常..? try {
    g();
    }catch(Exception e) {
    System.out.println("Caught in main(), e.printStackTrace()");
    e.printStackTrace();
    }catch(Throwable t) {
    System.err.println("测试捕捉Throwable异常.");
    }
      

  12.   

    因为你根本就没有抛出Throwable异常(确切地说,是没有抛出非Exception的Throwable异常),因为你抛出的Exception被第一个catch捕获到了,所以第二个catch就捕获不到了,但第二个catch必须存在,因为你有throws Throwable的声明。还有就是,捕获父类异常(如上面的Throwable)的catch必须在捕获子类异常(如上面的Exception)的catch的后面。这些《Thinking in JAVA》里面讲得很清楚了,楼主可以自己去看。