TJI读书笔记16-异常处理

 

 

概念

在早期没有专门的异常处理机制的时候,比如C语言,会通过一些约定俗成的东西来处理异常. 比如让程序返回某个特殊的值或者设置某个标记. 然后对返回值进行检查以判断程序是否出错. 还记得以前C语言的时候,return 0return -1对异常处理的实现可以追溯到BASIC中的on error goto语句. C++的异常处理机制基于Ada,而Java的异常处理是建立在C++之上的.

叫异常的意思是,问题出现了,但是可能还不知道该如何处理,但是确定这个问题不能置之不理,这个时候要停下来看看别人或者别的地方是不是能够处理这个问题. 换句话说就是:当前环境中没有足够的信息来解决遇到的问题的时候,就应该把问题提交给一个更高级别的环境中去解决 这也是异常处理的基本思路.
使用异常处理的好处是能够降低处理错误代码的复杂度. 它可以把正常的代码和出了问题需要处理的代码相分离.

基本异常情形

异常情形就是组织当前方法或作用域继续执行的问题. 不是出了所有问题都叫异常,如果当前环境下能够得到足够的信息,总能handle这个要处理的问题的时候,这种情形应该被视作普通情形不是异常. 只有在当前环境中得不到足够的信息来解决问题的时候,我们所能做的就是从当前环境跳出,并且把问题交给上一级环境. 异常处理所需要关注的点.

异常抛出后会发生的事情

  • 使用new在堆上创建一个异常对象.
  • 当前执行路径被终止,并且从当前环境中弹出对异常对象的引用
  • 异常处理机制接管程序,并循环早一个合适的地方继续执行程序(这个合适的地方就是异常处理程序)
  • 异常处理程序从错误状态中恢复,程序要么换一种方式运行,要么继续运行下去

比如,

1.if(t==null)
2. throw new NullPointerException

比如这一段代码,异常抛出以后,当前环境就不需要再为这个问题所操心了, 它会在别的地方得到处理.

异常参数
首先要知道,异常在java中也是一个new在堆上的对象. 也涉及存储空间的分配和构造器调用. 其中最常用的两个构造器分别是:

  • 无参构造器
  • String message的有参构造器

异常抛出的时候使用throw关键字,在new了异常对象之后,其引用会传递给throw. 看上去就像正常方法的return一样. 但是异常返回的地点和普通方法调用返回的地方不一样. 异常在一个恰当的异常处理程序中得到解决. 它的位置可能离异常抛出的地方很远,也可能会跨越方法调用栈的很多层次.

Throwable是所有异常的跟类,throw关键字可以用于抛出任何Throwable对象.

异常的捕获

要知道异常怎么捕获就得先了解”监控区域”的概念.
try块
简单来说,try块就是一个自定义的监控区域. 也就是在这个块里try可能产生异常的代码. 如果有问题就throw出去.

catch
抛出的异常必须得到处理,处理的底单就是”异常处理程序”.它会紧跟在try块之后,以关键字catche表示.

1.try {  
2. // Code that might generate exceptions
3.} catch(Type1 id1)|{
4. // Handle exceptions of Type1
5.} catch(Type2 id2) {
6. // Handle exceptions of Type2
7.} catch(Type3 id3) {
8. // Handle exceptions of Type3
9.}
10.
11.// etc...

catch块看上去就像仅接收一个特殊入参的方法. 这玩意儿跟方法的使用很相似. 异常处理机制搜参数和异常类型相匹配的第一个处理程序,然后进入catch子句执行. 需要注意的是,catch块有且仅有一个被执行.

终止与恢复
异常处理有两种模型,一种是终止模型. 这种模型下,假设异常错误非常关键,以至于程序无法回到异常发生的地方继续执行. 一旦异常被抛出,表明错误已经无法挽回,不能回头继续执行.
还有一种叫做恢复模型,意思是异常处理的工作是修正错误,然后尝试重新调用出问题的方法,并且认为第二次能成功.

java采用的是终止模型. 但是如果想让java实现恢复模型,可以将try块放在while循环里,这就会不断的进入try块直到得到满意的结果.

自定义异常

java提供的异常类型已经很丰富了. 但是如果有些时候需要自己去定义的话,也是可以的. 定义自己的异常类必须从已有的异常类型继承. 最简单的办法就是让编译器来产生构造器.

1.class SimpleException extends Exception{
2.
3.}
4.
5.public class InheritingExceptions{
6. public void f() throws SimpleException{
7. System.err.println("Throw SimpleException from f()");
8. throw new SimpleException();
9. }
10. public static void main(String[] args) {
11. InheritingExceptions sed = new InheritingExceptions();
12. try {
13. sed.f();
14. } catch (SimpleException e) {
15. // TODO: handle exception
16. System.out.println("catch it");
17. }
18. }
19.}

直接调用基类的默认构造器其实就可以了. 这里有必要提到的一点是,异常信息打印的位置. 打印到System.err的标准错误流是比较合适的. 因为标准输出流可能会被重定向. 而且把该送的东西送到它该去的地方,总是没错的.

1.class MyException extends Exception{
2. public MyException(){super();}
3. public MyException(String msg){
4. super(msg);
5. }
6.}
7.
8.public class FullConstructors {
9. public static void f() throws MyException{
10. System.out.println("throwing MyException from f()");
11. throw new MyException();
12. }
13. public static void g()throws MyException{
14. System.out.println("Throwing MyException from g()");
15. throw new MyException("Originated in g()");
16. }
17. public static void main(String[] args) {
18. try {
19. f();
20. } catch (MyException e) {
21. // TODO: handle exception
22. e.printStackTrace(System.out);
23. }
24. try {
25. g();
26. } catch (MyException e) {
27. // TODO: handle exception
28. e.printStackTrace(System.out);
29. }
30. }
31.}/*
32.throwing MyException from f()
33.ch12_Exception.MyException
34. at ch12_Exception.FullConstructors.f(FullConstructors.java:13)
35. at ch12_Exception.FullConstructors.main(FullConstructors.java:21)
36.Throwing MyException from g()
37.ch12_Exception.MyException: Originated in g()
38. at ch12_Exception.FullConstructors.g(FullConstructors.java:17)
39. at ch12_Exception.FullConstructors.main(FullConstructors.java:27)
40.
41.*/

这是带参数构造器和不带参数构造器打印内容的区别.

日志记录

1.import java.io.PrintWriter;
2.import java.io.StringWriter;
3.import java.util.logging.*;
4.
5.class LoggingExceptions extends Exception{
6. private static Logger logger = Logger.getLogger("Logging Execptions");
7. public LoggingExceptions(){
8. StringWriter trace = new StringWriter();
9. printStackTrace(new PrintWriter(trace));
10. logger.severe(trace.toString());
11. }
12.}
13.
14.public class LoggingException {
15. public static void main(String[] args) {
16. try {
17. throw new LoggingExceptions();
18. } catch (LoggingExceptions e) {
19. // TODO: handle exception
20. System.err.println("Caught "+e);
21. }
22.
23. try {
24. throw new LoggingExceptions();
25. } catch (LoggingExceptions e) {
26. // TODO: handle exception
27. System.err.println("Caught "+e);
28. }
29. }
30.}

向自定义异常类中定义其他成员
首先异常类也是一个类,它可以定义自己的成员方法和成员变量.

1.class MyException2 extends Exception{
2. private int x;
3. public MyException2(){
4. super();
5. }
6. public MyException2(String msg){
7. super(msg);
8. }
9. public MyException2(String msg,int x){
10. super(msg);
11. this.x = x;
12. }
13. public int val(){
14. return x;
15. }
16. public String getMessage(){
17. return "Detail Message: "+x+" "+super.getMessage();
18. }
19.}
20.public class ExtralFeature {
21. public static void f() throws MyException2{
22. System.out.println("Throwing MyExcetion2 from f()");
23. throw new MyException2();
24. }
25. public static void g() throws MyException2{
26. System.out.println("Throwing MyExcetion2 from g()");
27. throw new MyException2("Originated in g()");
28. }
29. public static void h() throws MyException2{
30. System.out.println("Throwing MyExcetion2 from h()");
31. throw new MyException2("Originated in h()",47);
32. }
33.
34. public static void main(String[] args) {
35. for(int i=0;i<5;i++){
36. try {
37. f();
38. } catch (MyException2 e) {
39. // TODO: handle exception
40. e.printStackTrace();
41. }
42. try {
43. g();
44. } catch (MyException2 e) {
45. // TODO: handle exception
46. e.printStackTrace();
47. }
48.
49. try {
50. h();
51. } catch (MyException2 e) {
52. // TODO: handle exception
53. e.printStackTrace();
54. System.out.println("e.val="+e.val());
55. }
56. System.out.println("========================================");
57. }
58. }
59.}

遇到一个问题, 预期跟实际输出不一样. 有点蒙了,刚发了个帖子问,还在等答案…

异常说明

java鼓励大家把方法肯能会抛出的异常告诉使用此方法的程序员. 这种做法可以让调用者知道该方法可能出现的异常.如果可以看到源码,那么在源码中可以知道方法可能会抛出的异常. 如果看不到源码岂不是蒙圈了. 所以java提供了一个throws关键字,跟在方法名称定义的后面,表示该方法内部可能会抛出的异常.
比如public void f() throws Exception1,Exception2,Exception3...如果没有throws的话,表示出了从RuntimeException继承的异常,它不会抛出任何其他异常.
需要注意的是,throws抛出的异常和代码中的说明必须一致. 也就是说,要么处理这个异常,要么在函数声明的时候抛出去. 但是可以在声明方法的时候throws异常,但实际代码上不throw. 也就是预先定义这个异常,以后不需要再修改这里的代码了. 这个在定义抽象类和接口的时候比较常用.

捕获所有异常

可以通过捕获异常类型的基类性Exception来用一个catch块捕获所有的异常. 但是用的时候,最好是将其放在所有catch块的最后. 这里就涉及到了java捕获异常的顺序了. java会按照代码的顺序,进入第一个匹配到的catch块. 正常来说,我们希望异常捕获的越精确越好. 所以在写多个catch块的时候,一般按照异常的”由小到大”的顺序来写.

Exception
Exception类是和编程相关的所有异常类的基类. 通过这类可以调用从Throwable类中调用的一些方法:

  • String getMessage() 返回一个简短描述信息
  • String getLocalizedMessage()
  • String toString()
  • void printStackTrace() 显示异常抛出地点的方法调用序列.
1.public class ExceptionMethod {
2. public static void main(String[] args) {
3. try {
4. throw new Exception("My exception");
5. } catch (Exception e) {
6. System.out.println("Caught Exception");
7. System.out.println("getMessage(): "+e.getMessage());
8. System.out.println("getLocalMessage():"+e.getLocalizedMessage());
9. System.out.println("toString():"+e.toString());
10. e.printStackTrace();
11. }
12. }
13.}/*output:
14.Caught Exception
15.getMessage(): My exception
16.getLocalMessage():My exception
17.toString():java.lang.Exception: My exception
18.java.lang.Exception: My exception
19. at ch12_Exception.ExceptionMethod.main(ExceptionMethod.java:6)
20.*/

异常的信息就是那么多,而每个方法是指选择不同的部分来显示. 其实每个方法都是前一个方法的超集.

栈轨迹

printStackTrace()方法所提供的信息可以通过getStackTrace()方法直接访问.这个方法返回一个由栈轨迹中的元素所构成的数组. 其中每个元素表示栈中的一帧. 0表示栈顶元素,也就是最后的一个方法调用.也是Throwable对象被创建和抛出的地方. 最后一个元素是第一个方法调用.

1.public class WhoCalled {
2. static void f(){
3. try {
4. throw new Exception();
5. } catch (Exception e) {
6. // TODO: handle exception
7. for(StackTraceElement ste:e.getStackTrace()){
8. System.out.println(ste.getMethodName());
9. }
10. }
11. }
12. static void g(){
13. f();
14. }
15. static void h(){
16. g();
17. }
18. public static void main(String[] args) {
19. f();
20. System.out.println("--------------------");
21. g();
22. System.out.println("--------------------");
23. h();
24. System.out.println("--------------------");
25. }
26.}/*
27.f
28.main
29.--------------------
30.f
31.g
32.main
33.--------------------
34.f
35.g
36.h
37.main
38.--------------------
39.*/

重新抛出异常

有时候我们需要在捕获异常之后重新抛出,尤其是使用Exception捕获所有异常的时候,既然已经拿到了异常的引用,可以直接再把它抛出去.重新抛出异常给上一级环境中的异常处理程序,同一个try块的后续catch子句将被忽略. 所以上一级环境中的异常处理程序可以对这个异常对象中拿到所有信息. 如果只是把当前对象重新抛出,那么上一级的异常处理程序得到将会是原来异常抛出点的栈调用信息. 而非新抛出点的信息. 果想要更新,可以调用fillInStackTrace(). 这将返回一个Throwable对象,它是通过当前调用栈信息填入原来那个异常对象而建立的.

1.public class Rethrowing {
2. public static void f() throws Exception{
3. System.out.println("origination exception in f()");
4. throw new Exception("throw from f()");
5. }
6. public static void g() throws Exception{
7. try{
8. f();
9. }catch (Exception e) {
10. // TODO: handle exception
11. System.out.println("Inside g(),e.printStackTrace()");
12. e.printStackTrace(System.out);
13. throw e;
14. }
15. }
16. public static void h() throws Exception{
17. try {
18. f();
19. } catch (Exception e) {
20. // TODO: handle exception
21. System.out.println("Inside h(),e.printStackTrace()");
22. e.printStackTrace(System.out);
23. throw (Exception)e.fillInStackTrace();
24. }
25. }
26. public static void main(String[] args) {
27. try {
28. g();
29. } catch (Exception e) {
30. // TODO: handle exception
31. System.out.println("Main:printStackTrace()");
32. e.printStackTrace(System.out);
33. }
34.
35. try {
36. h();
37. } catch (Exception e) {
38. // TODO: handle exception
39. System.out.println("Main:printStackTrace()");
40. e.printStackTrace(System.out);
41. }
42. }
43.}/*output:
44.origination exception in f()
45.Inside g(),e.printStackTrace()
46.java.lang.Exception: throw from f()
47. at ch12_Exception.Rethrowing.f(Rethrowing.java:6)
48. at ch12_Exception.Rethrowing.g(Rethrowing.java:10)
49. at ch12_Exception.Rethrowing.main(Rethrowing.java:30)
50.Main:printStackTrace()
51.java.lang.Exception: throw from f()
52. at ch12_Exception.Rethrowing.f(Rethrowing.java:6)
53. at ch12_Exception.Rethrowing.g(Rethrowing.java:10)
54. at ch12_Exception.Rethrowing.main(Rethrowing.java:30)
55.
56.
57.
58.origination exception in f()
59.Inside h(),e.printStackTrace()
60.java.lang.Exception: throw from f()
61. at ch12_Exception.Rethrowing.f(Rethrowing.java:6)
62. at ch12_Exception.Rethrowing.h(Rethrowing.java:20)
63. at ch12_Exception.Rethrowing.main(Rethrowing.java:38)
64.
65.Main:printStackTrace()
66.java.lang.Exception: throw from f()
67. at ch12_Exception.Rethrowing.h(Rethrowing.java:25)
68. at ch12_Exception.Rethrowing.main(Rethrowing.java:38)
69.*/

看67,68行,这里是执行了fillInStackTrace()之后的,异常抛出的地点.

当然,可以在catch块中抛出另外一个异常.

1.class OneException extends Exception{
2. public OneException(String s){
3. super(s);
4. }
5.}
6.class TwoException extends Exception{
7. public TwoException(String s){
8. super(s);
9. }
10.}
11.
12.public class ReThrowNew {
13. public static void f() throws OneException{
14. System.out.println("originating the exception in f()");
15. throw new OneException("throw from f()");
16. }
17. public static void main(String[] args) {
18. try {
19. try {
20. f();
21. } catch (OneException e) {
22. // TODO: handle exception
23. System.out.println("Caught in inner try,e.printStackTrace()");
24. e.printStackTrace(System.out);
25. throw new TwoException("from inner try");
26. }
27. } catch (TwoException e) {
28. // TODO: handle exception
29. System.out.println("Caught in outer try,e.printStackTrace()");
30. e.printStackTrace(System.out);
31.
32. }
33. }
34.}/*output:
35.originating the exception in f()
36.Caught in inner try,e.printStackTrace()
37.ch12_Exception.OneException: throw from f()
38. at ch12_Exception.ReThrowNew.f(ReThrowNew.java:17)
39. at ch12_Exception.ReThrowNew.main(ReThrowNew.java:22)
40.Caught in outer try,e.printStackTrace()
41.ch12_Exception.TwoException: from inner try
42. at ch12_Exception.ReThrowNew.main(ReThrowNew.java:27)
43.*/

后面这个异常,只有main方法才知道,f()方法对其一无所知.

Java标准异常

Throwable是java中任何可以作为异常被抛出的类.(注意,不是Exception,不是Exception,不是Exception) Throwable
对象可以分为两种类型:Error用来表示编译时和系统错误. Exception是可被抛出的基本类型. 在java类库,用户方法,以及运行时问题,都可能会抛出Exception. 这也是java程序员最关心的问题.

java的异常类型其实都很简单,主要是靠名字. java异常的概念,是使用名称表示发生的问题. 也就是通过名字就大概可以知道发生了什么问题. 所以在自定义异常的时候也要注意,不要起Exception1这种恶心的名字.

注意一个特例,RuntimeException. 运行时异常很多,比如空指针错,这些错误都继承自RuntimeException. 会被JVM自动抛出. 他们也被称为是不受检查的异常. 如果没有对RuntimeException异常进行捕获,那么,它就会穿越所有方法,直到main方法然后抛出,然后会调用printStackStrace(). 对于这种异常,不需要说明,其输出报告就直接到了System.err.

使用finally

一般抛出异常之后,方法就会被终止,在异常之后的代码就没有办法执行了. 但是有一些代码,比如关闭数据库连接,关闭流等,如果在执行之前抛出了异常,那就悲剧了. 所以一些出了内存回收之外的清理动作,是无论异常是否发生都要执行的. 怎么办呢,java提供了finally子句.

关于finally子句,只需要记住一句话,finally子句总会被执行. 无论是否有异常都会执行. 那么如果程序在try块中return了呢?

1.public class FianllyTest {
2. public static int f(int val){
3. try {
4. System.out.println("111");
5. if(val==1) return 1;
6. else if(val==2) return 2;
7. else return 23333;
8. } finally {
9. // TODO: handle finally clause
10. System.out.println("I am in finally block");
11. }
12. }
13. public static void main(String[] args) {
14. System.out.println(f(10));
15. System.out.println(f(1));
16. System.out.println(f(2));
17.
18. }
19.}/*output:
20.111
21.I am in finally block
22.23333
23.111
24.I am in finally block
25.1
26.111
27.I am in finally block
28.2
29.*/

看这个例子就明白了,finally子句总会被执行,即使try块中已经return了,它还是会执行的.

异常丢失

1.
2.class VeryImportantException extends Exception{
3. public String toString(){
4. return "A very important exception";
5. }
6.}
7.
8.class HoHumException extends Exception{
9. public String toString(){
10. return "a trival exception";
11. }
12.}
13.public class LostMessage {
14. void f() throws VeryImportantException{
15. throw new VeryImportantException();
16. }
17. void dispose()throws HoHumException{
18. throw new HoHumException();
19. }
20. public static void main(String[] args) {
21. try{
22. LostMessage lm = new LostMessage();
23. try{
24. lm.f();
25. }finally {
26. lm.dispose();
27. }
28. }catch (Exception e) {
29. // TODO: handle exception
30. System.out.println(e);
31. }
32.
33. }
34.}

看这么一个例子,VeryImportantException不见了. 只捕获到了HoHumException. 这种情况是不应该出现的,按照剧本来说,这种情况是不应该出现的.按照C++的思路,前一个异常还没有处理就抛出下一个异常,这是不应该的. 但是java并没有对其做很好的检查. 在使用try-finall结构的时候很有可能会出现这种情况. 所以暂时,或许我们只能靠良好的编程习惯来解决它. 尽量使用try-catch-finally结构.

1.try{
2. lm.f();
3. }catch (Exception e) {
4. // TODO: handle exception
5. System.out.println(e);
6. }
7. finally {
8. lm.dispose();
9. }

异常的限制

所谓异常限制就是,当覆盖方法的时候,只能抛出基类方法的异常说明中列出来的那些异常.这个限制很有用,当基类的代码应用到其派生类的时候,一样能够工作.

1.//: exceptions/StormyInning.java 
2.//Overridden methods may throw only the exceptions
3.//specified in their base-class versions, or exceptions
4.//derived from the base-class exceptions.
5.
6.class BaseballException extends Exception {
7.}
8.
9.class Foul extends BaseballException {
10.}
11.
12.class Strike extends BaseballException {
13.}
14.
15.abstract class Inning {
16. public Inning() throws BaseballException {
17. }
18.
19. public void event() throws BaseballException {
20. // Doesn’t actually have to throw anything
21. }
22.
23. public abstract void atBat() throws Strike, Foul;
24.
25. public void walk() {
26. } // Throws no checked exceptions
27.}
28.
29.class StormException extends Exception {
30.}
31.
32.class RainedOut extends StormException {
33.}
34.
35.class PopFoul extends Foul {
36.}
37.
38.interface Storm {
39. public void event() throws RainedOut;
40.
41. public void rainHard() throws RainedOut;
42.}
43.
44.public class StormyInning extends Inning implements Storm {
45. // OK to add new exceptions for constructors, but you
46. // must deal with the base constructor exceptions:
47. public StormyInning() throws RainedOut, BaseballException {
48. }
49.
50. public StormyInning(String s) throws Foul, BaseballException {
51. }
52.
53. // Regular methods must conform to base class:
54. // ! void walk() throws PopFoul {} //Compile error
55. // Interface CANNOT add exceptions to existing
56. // methods from the base class:
57. // ! public void event() throws RainedOut {}
58. // If the method doesn’t already exist in the
59. // base class, the exception is OK:
60. public void rainHard() throws RainedOut {
61. }
62.
63. // You can choose to not throw any exceptions,
64. // even if the base version does:
65. public void event() {
66. }
67.
68. // Overridden methods can throw inherited exceptions:
69. public void atBat() throws PopFoul {
70. }
71.
72. public static void main(String[] args) {
73. try {
74. StormyInning si = new StormyInning();
75. si.atBat();
76. } catch (PopFoul e) {
77. System.out.println("Pop foul");
78. } catch (RainedOut e) {
79. System.out.println("Rained out");
80. } catch (BaseballException e) {
81. System.out.println("Generic baseball exception");
82. }
83. // Strike not thrown in derived version.
84. try {
85. // What happens if you upcast?
86. Inning i = new StormyInning();
87. i.atBat();
88. // You must catch the exceptions from the
89. // base-class version of the method:
90. } catch (Strike e) {
91. System.out.println("Strike");
92. } catch (Foul e) {
93. System.out.println("Foul");
94. } catch (RainedOut e) {
95. System.out.println("Rained out");
96. } catch (BaseballException e) {
97. System.out.println("Generic baseball exception");
98. }
99. }
100.} /// :~
101.

看埃大爷的书学了不少单词…

  • 在Inning类中,构造器和event()方法都声明要抛出异常,实际上却没有抛出. 这种方式可以强制让用户去捕获可能在重写后增加的异常.对于抽象方法,同样适用.
  • Storm接口中,包含了一个Inning定义的event()方法和不再Inning中定义的rainHard方法. 这两个方法都抛出新的异常,RainedOut. 如果扩展类中继承了Inning类又实现了Storm接口,那么在扩展类中就不能改变基类的throws的异常列表. 所以在扩展类中,可以看到event()方法没有抛出异常.
  • 如果接口中定义的方法没有和基类中的重名,比如rainHard(),那么此方法,抛出什么样的异常都无所谓.
  • 异常限制对构造器不起作用. 但是,因为基类构造器在扩展类中必须被调用. 所以派生类的构造器必须抛出包含基类构造器所抛出的异常
  • walk()方法不能通过编译,是因为在基类中它并没抛出异常,但是在扩展类中抛了. 这个是不可以的.
  • event()方法没有抛出异常,atBat()方法抛出的异常是基类异常说明的子集,这个都是允许的,因为在向上转型之后,并不会造成基类方法失效.
  • 关于main()方法,注意,在向上转型之后,编译器会要求按照基类所抛出的异常来处理.

注意,在继承的过程中,编译器会要求对异常做强制说明. 但是这并不表示异常列表本身属于方法类型的一部分. 方法签名仅包括方法名和形参列表. 上面balabalabala那么多,其实就说明了一个问题,子类的异常说明列表必须要”小于等于”基类的. 结合之前说过,方法可以throws异常但是在方法体内不抛出. 那么这种限制就使得程序更加健壮.

构造器

异常发生的时候,最麻烦的事情是该清理的东西是否都清理了. 绝大多数情况下, 飞机在起飞和降落的时候最危险,对象在生成和销毁的时候最危险. 因为这都不是稳定状态. 如果构造器内部出现了异常,清理行为或许就不能正常工作了. 使用try-catch-finally结构都可以安全的解决这个问题. 但是如果是构造器就麻烦了.因为finally总会执行,如果在构造器中使用finally块来进行清理的话,那么创建的对象在构造器中就被清理了. 咋整???

1.public class InputFile {
2. private BufferedReader in;
3. public InputFile(String filename) throws Exception{
4. try{
5. in = new BufferedReader(new FileReader(filename));
6. }catch (FileNotFoundException e) {
7. // TODO: handle exception
8. System.out.println("can not open the fire"+filename);
9. throw e;
10. }catch (Exception e) {
11. // TODO: handle exception
12. try{
13. in.close();
14. }catch (IOException e2) {
15. // TODO: handle exception
16. System.out.println("in.close() unsuccessful");
17. }
18. throw e;
19. }finally {
20. //没有操作
21. }
22. }
23. public String getLine(){
24. String s;
25. try{
26. s = in.readLine();
27. }catch (IOException e) {
28. // TODO: handle exception
29. throw new RuntimeException("readline() failed");
30. }
31. return s;
32. }
33. public void dispose(){
34. try {
35. in.close();
36. System.out.println("close success");
37. } catch (IOException e2) {
38. // TODO: handle exception
39. throw new RuntimeException("in.close() failed");
40. }
41. }
42.}

注意3-22行的构造器. 如果FileReader的构造器实白了,抛出FileNotFoundException异常,对于这个异常,不需要关闭文件,因为文件还没有打开. 而其他捕获到异常的catch语句就需要关闭文件了. 做完本地处理之后,异常被重新抛出,对于构造器而言,这是很合适的做法. 因为这样不会误导调用者,让他认为已经构造成功了.
对于构造阶段就可能会抛出异常的类,最安全的做法是使用嵌套的try子句来处理.

1.public class Cleanup {
2. public static void main(String[] args) {
3. try {
4. InputFile in = new InputFile("Cleanup.java");
5. try{
6. String s;
7. int i =1;
8. while((s=in.getLine())!=null){
9. //...
10. }
11. }catch (Exception e) {
12. // TODO: handle exception
13. System.out.println("caught exception in main");
14. e.printStackTrace(System.out);
15. }finally{
16. in.dispose();
17. }
18. } catch (Exception e) {
19. // TODO: handle exception
20. System.out.println("input file construction failed");
21. }
22. }
23.}

第4行代码,如果构造实白直接会进入自己的catch语句块,也就是18行. 这样的话,dispose()语句也不会被调用. 而如果构造成功会进入内层try块执行. 在这种方法中,finally子句在构造失败的时候不会被执行. 而构造成功的时候总是会被执行. 但是,这种办法虽然能解决问题,但是在绝大部分情况下,还是需要清理对象的时候,立即进入finally块中.

1.class NeedCleanup {
2. private static long counter = 1;
3. private final long id = counter++;
4.
5. public void dispose() {
6. System.out.println("need cleanup " + id + " disposed");
7. }
8.}
9.
10.class ConstructionException extends Exception {
11.
12.}
13.
14.class NeedCleanup2 extends NeedCleanup {
15. public NeedCleanup2() throws ConstructionException {
16.
17. }
18.}
19.
20.public class CleanupIdiom {
21. public static void main(String[] args) {
22. //section1
23. NeedCleanup nc1 = new NeedCleanup();
24. try {
25.
26. } finally {
27. nc1.dispose();
28. }
29. //section2
30. NeedCleanup nc2 = new NeedCleanup();
31. NeedCleanup nc3 = new NeedCleanup();
32. try {
33.
34. } finally {
35. nc3.dispose();
36. nc2.dispose();
37. }
38. //section3
39. try {
40. NeedCleanup2 nc4 = new NeedCleanup2();
41. try {
42. NeedCleanup2 nc5 = new NeedCleanup2();
43. try {
44. // ....
45. } finally {
46. nc5.dispose();
47. }
48. } catch (ConstructionException e) {
49. System.out.println(e);
50. }
51.
52. finally {
53. nc4.dispose();
54. }
55. } catch (ConstructionException e) {
56. System.out.println(e);
57. }
58. }
59.}

section1 就是一个简单的try-finally原则. section2为了构造和清理,可以看到具有不能失败的构造器的对象组合在一起
section3展示了如何处理可以失败的构造器且需要清理的对象. (可绕死我了…)

异常的匹配

一句话,实在懒得写了,在抛出异常之后,异常处理程序会按照代码的书写顺序,找出”最近”的匹配上的处理代码. 这里所谓的匹配,包括其基类. 所以在书写的时候,最好按照”由小到大”的顺序来书写.

其他乱七八糟

异常处理的一个重要原则,在你知道如何处理的情况下才捕获它. 实际上异常处理的一个重要目标就是将错误处理的代码和发生错误的地点相分离.

%23TJI%u8BFB%u4E66%u7B14%u8BB016-%u5F02%u5E38%u5904%u7406%0A@%28034.java%29%5Bjava%7Cjava%u7F16%u7A0B%u601D%u60F3%5D%0A%0A%5BTOC%5D%0A%0A%23%23%u6982%u5FF5%0A%u5728%u65E9%u671F%u6CA1%u6709%u4E13%u95E8%u7684%u5F02%u5E38%u5904%u7406%u673A%u5236%u7684%u65F6%u5019%2C%u6BD4%u5982C%u8BED%u8A00%2C%u4F1A%u901A%u8FC7%u4E00%u4E9B%u7EA6%u5B9A%u4FD7%u6210%u7684%u4E1C%u897F%u6765%u5904%u7406%u5F02%u5E38.%20%u6BD4%u5982%u8BA9%u7A0B%u5E8F%u8FD4%u56DE%u67D0%u4E2A%u7279%u6B8A%u7684%u503C%u6216%u8005%u8BBE%u7F6E%u67D0%u4E2A%u6807%u8BB0.%20%u7136%u540E%u5BF9%u8FD4%u56DE%u503C%u8FDB%u884C%u68C0%u67E5%u4EE5%u5224%u65AD%u7A0B%u5E8F%u662F%u5426%u51FA%u9519.%20%u8FD8%u8BB0%u5F97%u4EE5%u524DC%u8BED%u8A00%u7684%u65F6%u5019%2C%60return%200%60%u548C%60return%20-1%60%u5BF9%u5F02%u5E38%u5904%u7406%u7684%u5B9E%u73B0%u53EF%u4EE5%u8FFD%u6EAF%u5230BASIC%u4E2D%u7684%60on%20error%20goto%60%u8BED%u53E5.%20C++%u7684%u5F02%u5E38%u5904%u7406%u673A%u5236%u57FA%u4E8EAda%2C%u800CJava%u7684%u5F02%u5E38%u5904%u7406%u662F%u5EFA%u7ACB%u5728C++%u4E4B%u4E0A%u7684.%20%0A%0A%u53EB%u5F02%u5E38%u7684%u610F%u601D%u662F%2C%u95EE%u9898%u51FA%u73B0%u4E86%2C%u4F46%u662F%u53EF%u80FD%u8FD8%u4E0D%u77E5%u9053%u8BE5%u5982%u4F55%u5904%u7406%2C%u4F46%u662F%u786E%u5B9A%u8FD9%u4E2A%u95EE%u9898%u4E0D%u80FD%u7F6E%u4E4B%u4E0D%u7406%2C%u8FD9%u4E2A%u65F6%u5019%u8981%u505C%u4E0B%u6765%u770B%u770B%u522B%u4EBA%u6216%u8005%u522B%u7684%u5730%u65B9%u662F%u4E0D%u662F%u80FD%u591F%u5904%u7406%u8FD9%u4E2A%u95EE%u9898.%20%u6362%u53E5%u8BDD%u8BF4%u5C31%u662F%3A**%u5F53%u524D%u73AF%u5883%u4E2D%u6CA1%u6709%u8DB3%u591F%u7684%u4FE1%u606F%u6765%u89E3%u51B3%u9047%u5230%u7684%u95EE%u9898%u7684%u65F6%u5019%2C%u5C31%u5E94%u8BE5%u628A%u95EE%u9898%u63D0%u4EA4%u7ED9%u4E00%u4E2A%u66F4%u9AD8%u7EA7%u522B%u7684%u73AF%u5883%u4E2D%u53BB%u89E3%u51B3**%20%u8FD9%u4E5F%u662F%u5F02%u5E38%u5904%u7406%u7684%u57FA%u672C%u601D%u8DEF.%20%0A%u4F7F%u7528%u5F02%u5E38%u5904%u7406%u7684%u597D%u5904%u662F%u80FD%u591F%u964D%u4F4E%u5904%u7406%u9519%u8BEF%u4EE3%u7801%u7684%u590D%u6742%u5EA6.%20%u5B83%u53EF%u4EE5%u628A%u6B63%u5E38%u7684%u4EE3%u7801%u548C%u51FA%u4E86%u95EE%u9898%u9700%u8981%u5904%u7406%u7684%u4EE3%u7801%u76F8%u5206%u79BB.%20%0A%0A%23%23%u57FA%u672C%u5F02%u5E38%u60C5%u5F62%0A%0A%u5F02%u5E38%u60C5%u5F62%u5C31%u662F%u7EC4%u7EC7%u5F53%u524D%u65B9%u6CD5%u6216%u4F5C%u7528%u57DF%u7EE7%u7EED%u6267%u884C%u7684%u95EE%u9898.%20%u4E0D%u662F%u51FA%u4E86%u6240%u6709%u95EE%u9898%u90FD%u53EB%u5F02%u5E38%2C%u5982%u679C%u5F53%u524D%u73AF%u5883%u4E0B%u80FD%u591F%u5F97%u5230%u8DB3%u591F%u7684%u4FE1%u606F%2C%u603B%u80FDhandle%u8FD9%u4E2A%u8981%u5904%u7406%u7684%u95EE%u9898%u7684%u65F6%u5019%2C%u8FD9%u79CD%u60C5%u5F62%u5E94%u8BE5%u88AB%u89C6%u4F5C%u666E%u901A%u60C5%u5F62%u4E0D%u662F%u5F02%u5E38.%20%u53EA%u6709%u5728%u5F53%u524D%u73AF%u5883%u4E2D%u5F97%u4E0D%u5230%u8DB3%u591F%u7684%u4FE1%u606F%u6765%u89E3%u51B3%u95EE%u9898%u7684%u65F6%u5019%2C%u6211%u4EEC%u6240%u80FD%u505A%u7684%u5C31%u662F%u4ECE%u5F53%u524D%u73AF%u5883%u8DF3%u51FA%2C%u5E76%u4E14%u628A%u95EE%u9898%u4EA4%u7ED9%u4E0A%u4E00%u7EA7%u73AF%u5883.%20%u5F02%u5E38%u5904%u7406%u6240%u9700%u8981%u5173%u6CE8%u7684%u70B9.%20%0A%0A**%u5F02%u5E38%u629B%u51FA%u540E%u4F1A%u53D1%u751F%u7684%u4E8B%u60C5**%0A-%20%u4F7F%u7528new%u5728%u5806%u4E0A%u521B%u5EFA%u4E00%u4E2A%u5F02%u5E38%u5BF9%u8C61.%20%0A-%20%u5F53%u524D%u6267%u884C%u8DEF%u5F84%u88AB%u7EC8%u6B62%2C%u5E76%u4E14%u4ECE%u5F53%u524D%u73AF%u5883%u4E2D%u5F39%u51FA%u5BF9%u5F02%u5E38%u5BF9%u8C61%u7684%u5F15%u7528%0A-%20%u5F02%u5E38%u5904%u7406%u673A%u5236%u63A5%u7BA1%u7A0B%u5E8F%2C%u5E76%u5FAA%u73AF%u65E9%u4E00%u4E2A%u5408%u9002%u7684%u5730%u65B9%u7EE7%u7EED%u6267%u884C%u7A0B%u5E8F%28%u8FD9%u4E2A%u5408%u9002%u7684%u5730%u65B9%u5C31%u662F%u5F02%u5E38%u5904%u7406%u7A0B%u5E8F%29%0A-%20%u5F02%u5E38%u5904%u7406%u7A0B%u5E8F%u4ECE%u9519%u8BEF%u72B6%u6001%u4E2D%u6062%u590D%2C%u7A0B%u5E8F%u8981%u4E48%u6362%u4E00%u79CD%u65B9%u5F0F%u8FD0%u884C%2C%u8981%u4E48%u7EE7%u7EED%u8FD0%u884C%u4E0B%u53BB%0A%0A%0A%u6BD4%u5982%2C%0A%60%60%60%0Aif%28t%3D%3Dnull%29%0A%09throw%20new%20NullPointerException%0A%60%60%60%0A%u6BD4%u5982%u8FD9%u4E00%u6BB5%u4EE3%u7801%2C%u5F02%u5E38%u629B%u51FA%u4EE5%u540E%2C%u5F53%u524D%u73AF%u5883%u5C31%u4E0D%u9700%u8981%u518D%u4E3A%u8FD9%u4E2A%u95EE%u9898%u6240%u64CD%u5FC3%u4E86%2C%20%u5B83%u4F1A%u5728%u522B%u7684%u5730%u65B9%u5F97%u5230%u5904%u7406.%20%0A%0A%0A**%u5F02%u5E38%u53C2%u6570**%0A%u9996%u5148%u8981%u77E5%u9053%2C%u5F02%u5E38%u5728java%u4E2D%u4E5F%u662F%u4E00%u4E2Anew%u5728%u5806%u4E0A%u7684%u5BF9%u8C61.%20%u4E5F%u6D89%u53CA%u5B58%u50A8%u7A7A%u95F4%u7684%u5206%u914D%u548C%u6784%u9020%u5668%u8C03%u7528.%20%u5176%u4E2D%u6700%u5E38%u7528%u7684%u4E24%u4E2A%u6784%u9020%u5668%u5206%u522B%u662F%3A%0A-%20%u65E0%u53C2%u6784%u9020%u5668%0A-%20%u5E26%60String%20message%60%u7684%u6709%u53C2%u6784%u9020%u5668%0A%0A%u5F02%u5E38%u629B%u51FA%u7684%u65F6%u5019%u4F7F%u7528throw%u5173%u952E%u5B57%2C%u5728new%u4E86%u5F02%u5E38%u5BF9%u8C61%u4E4B%u540E%2C%u5176%u5F15%u7528%u4F1A%u4F20%u9012%u7ED9throw.%20%u770B%u4E0A%u53BB%u5C31%u50CF%u6B63%u5E38%u65B9%u6CD5%u7684return%u4E00%u6837.%20%u4F46%u662F%u5F02%u5E38%u8FD4%u56DE%u7684%u5730%u70B9%u548C%u666E%u901A%u65B9%u6CD5%u8C03%u7528%u8FD4%u56DE%u7684%u5730%u65B9%u4E0D%u4E00%u6837.%20%u5F02%u5E38%u5728%u4E00%u4E2A%u6070%u5F53%u7684%u5F02%u5E38%u5904%u7406%u7A0B%u5E8F%u4E2D%u5F97%u5230%u89E3%u51B3.%20%u5B83%u7684%u4F4D%u7F6E%u53EF%u80FD%u79BB%u5F02%u5E38%u629B%u51FA%u7684%u5730%u65B9%u5F88%u8FDC%2C%u4E5F%u53EF%u80FD%u4F1A%u8DE8%u8D8A%u65B9%u6CD5%u8C03%u7528%u6808%u7684%u5F88%u591A%u5C42%u6B21.%20%0A%0AThrowable%u662F%u6240%u6709%u5F02%u5E38%u7684%u8DDF%u7C7B%2Cthrow%u5173%u952E%u5B57%u53EF%u4EE5%u7528%u4E8E%u629B%u51FA%u4EFB%u4F55Throwable%u5BF9%u8C61.%20%0A%0A%23%23%u5F02%u5E38%u7684%u6355%u83B7%0A%u8981%u77E5%u9053%u5F02%u5E38%u600E%u4E48%u6355%u83B7%u5C31%u5F97%u5148%u4E86%u89E3%22%u76D1%u63A7%u533A%u57DF%22%u7684%u6982%u5FF5.%20%0A**try%u5757**%0A%u7B80%u5355%u6765%u8BF4%2Ctry%u5757%u5C31%u662F%u4E00%u4E2A%u81EA%u5B9A%u4E49%u7684%u76D1%u63A7%u533A%u57DF.%20%u4E5F%u5C31%u662F%u5728%u8FD9%u4E2A%u5757%u91CCtry%u53EF%u80FD%u4EA7%u751F%u5F02%u5E38%u7684%u4EE3%u7801.%20%u5982%u679C%u6709%u95EE%u9898%u5C31throw%u51FA%u53BB.%0A%0A**catch**%0A%u629B%u51FA%u7684%u5F02%u5E38%u5FC5%u987B%u5F97%u5230%u5904%u7406%2C%u5904%u7406%u7684%u5E95%u5355%u5C31%u662F%22%u5F02%u5E38%u5904%u7406%u7A0B%u5E8F%22.%u5B83%u4F1A%u7D27%u8DDF%u5728try%u5757%u4E4B%u540E%2C%u4EE5%u5173%u952E%u5B57catche%u8868%u793A.%20%0A%60%60%60java%0Atry%20%7B%20%20%0A%20%20//%20Code%20that%20might%20generate%20exceptions%20%20%0A%7D%20catch%28Type1%20id1%29%7C%7B%20%20%0A%20%20//%20Handle%20exceptions%20of%20Type1%20%20%0A%7D%20catch%28Type2%20id2%29%20%7B%20%20%0A%20%20//%20Handle%20exceptions%20of%20Type2%20%20%0A%7D%20catch%28Type3%20id3%29%20%7B%20%20%0A%20%20//%20Handle%20exceptions%20of%20Type3%20%20%0A%7D%20%20%0A%20%0A//%20etc...%20%0A%60%60%60%0A%0Acatch%u5757%u770B%u4E0A%u53BB%u5C31%u50CF%u4EC5%u63A5%u6536%u4E00%u4E2A%u7279%u6B8A%u5165%u53C2%u7684%u65B9%u6CD5.%20%u8FD9%u73A9%u610F%u513F%u8DDF%u65B9%u6CD5%u7684%u4F7F%u7528%u5F88%u76F8%u4F3C.%20%u5F02%u5E38%u5904%u7406%u673A%u5236%u641C%u53C2%u6570%u548C%u5F02%u5E38%u7C7B%u578B%u76F8%u5339%u914D%u7684%u7B2C%u4E00%u4E2A%u5904%u7406%u7A0B%u5E8F%2C%u7136%u540E%u8FDB%u5165catch%u5B50%u53E5%u6267%u884C.%20%u9700%u8981%u6CE8%u610F%u7684%u662F%2Ccatch%u5757%u6709%u4E14%u4EC5%u6709%u4E00%u4E2A%u88AB%u6267%u884C.%20%0A%0A**%u7EC8%u6B62%u4E0E%u6062%u590D**%0A%u5F02%u5E38%u5904%u7406%u6709%u4E24%u79CD%u6A21%u578B%2C%u4E00%u79CD%u662F**%u7EC8%u6B62%u6A21%u578B**.%20%u8FD9%u79CD%u6A21%u578B%u4E0B%2C%u5047%u8BBE%u5F02%u5E38%u9519%u8BEF%u975E%u5E38%u5173%u952E%2C%u4EE5%u81F3%u4E8E%u7A0B%u5E8F%u65E0%u6CD5%u56DE%u5230%u5F02%u5E38%u53D1%u751F%u7684%u5730%u65B9%u7EE7%u7EED%u6267%u884C.%20%u4E00%u65E6%u5F02%u5E38%u88AB%u629B%u51FA%2C%u8868%u660E%u9519%u8BEF%u5DF2%u7ECF%u65E0%u6CD5%u633D%u56DE%2C%u4E0D%u80FD%u56DE%u5934%u7EE7%u7EED%u6267%u884C.%20%0A%u8FD8%u6709%u4E00%u79CD%u53EB%u505A**%u6062%u590D%u6A21%u578B**%2C%u610F%u601D%u662F%u5F02%u5E38%u5904%u7406%u7684%u5DE5%u4F5C%u662F%u4FEE%u6B63%u9519%u8BEF%2C%u7136%u540E%u5C1D%u8BD5%u91CD%u65B0%u8C03%u7528%u51FA%u95EE%u9898%u7684%u65B9%u6CD5%2C%u5E76%u4E14%u8BA4%u4E3A%u7B2C%u4E8C%u6B21%u80FD%u6210%u529F.%20%0A%0Ajava%u91C7%u7528%u7684%u662F%u7EC8%u6B62%u6A21%u578B.%20%u4F46%u662F%u5982%u679C%u60F3%u8BA9java%u5B9E%u73B0%u6062%u590D%u6A21%u578B%2C%u53EF%u4EE5%u5C06try%u5757%u653E%u5728while%u5FAA%u73AF%u91CC%2C%u8FD9%u5C31%u4F1A%u4E0D%u65AD%u7684%u8FDB%u5165try%u5757%u76F4%u5230%u5F97%u5230%u6EE1%u610F%u7684%u7ED3%u679C.%20%0A%0A%23%23%u81EA%u5B9A%u4E49%u5F02%u5E38%0A%0Ajava%u63D0%u4F9B%u7684%u5F02%u5E38%u7C7B%u578B%u5DF2%u7ECF%u5F88%u4E30%u5BCC%u4E86.%20%u4F46%u662F%u5982%u679C%u6709%u4E9B%u65F6%u5019%u9700%u8981%u81EA%u5DF1%u53BB%u5B9A%u4E49%u7684%u8BDD%2C%u4E5F%u662F%u53EF%u4EE5%u7684.%20%u5B9A%u4E49%u81EA%u5DF1%u7684%u5F02%u5E38%u7C7B%u5FC5%u987B%u4ECE%u5DF2%u6709%u7684%u5F02%u5E38%u7C7B%u578B%u7EE7%u627F.%20%u6700%u7B80%u5355%u7684%u529E%u6CD5%u5C31%u662F%u8BA9%u7F16%u8BD1%u5668%u6765%u4EA7%u751F%u6784%u9020%u5668.%20%0A%60%60%60java%0Aclass%20SimpleException%20extends%20Exception%7B%0A%09%0A%7D%0A%0Apublic%20class%20InheritingExceptions%7B%0A%09public%20void%20f%28%29%20throws%20SimpleException%7B%0A%09%09System.err.println%28%22Throw%20SimpleException%20from%20f%28%29%22%29%3B%0A%09%09throw%20new%20SimpleException%28%29%3B%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09InheritingExceptions%20sed%20%3D%20new%20InheritingExceptions%28%29%3B%0A%09%09try%20%7B%0A%09%09%09sed.f%28%29%3B%0A%09%09%7D%20catch%20%28SimpleException%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.out.println%28%22catch%20it%22%29%3B%0A%09%09%7D%0A%09%7D%0A%7D%0A%60%60%60%0A%u76F4%u63A5%u8C03%u7528%u57FA%u7C7B%u7684%u9ED8%u8BA4%u6784%u9020%u5668%u5176%u5B9E%u5C31%u53EF%u4EE5%u4E86.%20%u8FD9%u91CC%u6709%u5FC5%u8981%u63D0%u5230%u7684%u4E00%u70B9%u662F%2C%u5F02%u5E38%u4FE1%u606F%u6253%u5370%u7684%u4F4D%u7F6E.%20%u6253%u5370%u5230System.err%u7684%u6807%u51C6%u9519%u8BEF%u6D41%u662F%u6BD4%u8F83%u5408%u9002%u7684.%20%u56E0%u4E3A%u6807%u51C6%u8F93%u51FA%u6D41%u53EF%u80FD%u4F1A%u88AB%u91CD%u5B9A%u5411.%20%u800C%u4E14%u628A%u8BE5%u9001%u7684%u4E1C%u897F%u9001%u5230%u5B83%u8BE5%u53BB%u7684%u5730%u65B9%2C%u603B%u662F%u6CA1%u9519%u7684.%20%0A%0A%60%60%60java%0Aclass%20MyException%20extends%20Exception%7B%0A%09public%20MyException%28%29%7Bsuper%28%29%3B%7D%0A%09public%20MyException%28String%20msg%29%7B%0A%09%09super%28msg%29%3B%0A%09%7D%0A%7D%0A%0Apublic%20class%20FullConstructors%20%7B%0A%09public%20static%20void%20f%28%29%20throws%20MyException%7B%0A%09%09System.out.println%28%22throwing%20MyException%20from%20f%28%29%22%29%3B%0A%09%09throw%20new%20MyException%28%29%3B%0A%09%7D%20%0A%09public%20static%20void%20g%28%29throws%20MyException%7B%0A%09%09System.out.println%28%22Throwing%20MyException%20from%20g%28%29%22%29%3B%0A%09%09throw%20new%20MyException%28%22Originated%20in%20g%28%29%22%29%3B%0A%09%7D%20%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09try%20%7B%0A%09%09%09f%28%29%3B%0A%09%09%7D%20catch%20%28MyException%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%7D%0A%09%09try%20%7B%0A%09%09%09g%28%29%3B%0A%09%09%7D%20catch%20%28MyException%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%7D%0A%09%7D%0A%7D/*%0Athrowing%20MyException%20from%20f%28%29%0Ach12_Exception.MyException%0A%09at%20ch12_Exception.FullConstructors.f%28FullConstructors.java%3A13%29%0A%09at%20ch12_Exception.FullConstructors.main%28FullConstructors.java%3A21%29%0AThrowing%20MyException%20from%20g%28%29%0Ach12_Exception.MyException%3A%20Originated%20in%20g%28%29%0A%09at%20ch12_Exception.FullConstructors.g%28FullConstructors.java%3A17%29%0A%09at%20ch12_Exception.FullConstructors.main%28FullConstructors.java%3A27%29%0A%0A*/%0A%60%60%60%0A%u8FD9%u662F%u5E26%u53C2%u6570%u6784%u9020%u5668%u548C%u4E0D%u5E26%u53C2%u6570%u6784%u9020%u5668%u6253%u5370%u5185%u5BB9%u7684%u533A%u522B.%20%0A%0A**%u65E5%u5FD7%u8BB0%u5F55**%0A%0A%60%60%60java%0Aimport%20java.io.PrintWriter%3B%0Aimport%20java.io.StringWriter%3B%0Aimport%20java.util.logging.*%3B%0A%0Aclass%20LoggingExceptions%20extends%20Exception%7B%0A%09private%20static%20Logger%20logger%20%3D%20Logger.getLogger%28%22Logging%20Execptions%22%29%3B%0A%09public%20LoggingExceptions%28%29%7B%0A%09%09StringWriter%20trace%20%3D%20new%20StringWriter%28%29%3B%0A%09%09printStackTrace%28new%20PrintWriter%28trace%29%29%3B%0A%09%09logger.severe%28trace.toString%28%29%29%3B%0A%09%7D%0A%7D%0A%0Apublic%20class%20LoggingException%20%7B%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09try%20%7B%0A%09%09%09throw%20new%20LoggingExceptions%28%29%3B%0A%09%09%7D%20catch%20%28LoggingExceptions%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.err.println%28%22Caught%20%22+e%29%3B%0A%09%09%7D%0A%09%09%0A%09%09try%20%7B%0A%09%09%09throw%20new%20LoggingExceptions%28%29%3B%0A%09%09%7D%20catch%20%28LoggingExceptions%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.err.println%28%22Caught%20%22+e%29%3B%0A%09%09%7D%0A%09%7D%0A%7D%0A%60%60%60%0A%0A**%u5411%u81EA%u5B9A%u4E49%u5F02%u5E38%u7C7B%u4E2D%u5B9A%u4E49%u5176%u4ED6%u6210%u5458**%0A%u9996%u5148%u5F02%u5E38%u7C7B%u4E5F%u662F%u4E00%u4E2A%u7C7B%2C%u5B83%u53EF%u4EE5%u5B9A%u4E49%u81EA%u5DF1%u7684%u6210%u5458%u65B9%u6CD5%u548C%u6210%u5458%u53D8%u91CF.%20%0A%60%60%60java%0Aclass%20MyException2%20extends%20Exception%7B%0A%09private%20int%20x%3B%0A%09public%20MyException2%28%29%7B%0A%09%09super%28%29%3B%0A%09%7D%0A%09public%20MyException2%28String%20msg%29%7B%0A%09%09super%28msg%29%3B%0A%09%7D%0A%09public%20MyException2%28String%20msg%2Cint%20x%29%7B%0A%09%09super%28msg%29%3B%0A%09%09this.x%20%3D%20x%3B%0A%09%7D%0A%09public%20int%20val%28%29%7B%0A%09%09return%20x%3B%0A%09%7D%0A%09public%20String%20getMessage%28%29%7B%0A%09%09return%20%22Detail%20Message%3A%20%22+x+%22%20%22+super.getMessage%28%29%3B%0A%09%7D%0A%7D%0Apublic%20class%20ExtralFeature%20%7B%0A%09public%20static%20void%20f%28%29%20throws%20MyException2%7B%0A%09%09System.out.println%28%22Throwing%20MyExcetion2%20from%20f%28%29%22%29%3B%0A%09%09throw%20new%20MyException2%28%29%3B%0A%09%7D%20%0A%09public%20static%20void%20g%28%29%20throws%20MyException2%7B%0A%09%09System.out.println%28%22Throwing%20MyExcetion2%20from%20g%28%29%22%29%3B%0A%09%09throw%20new%20MyException2%28%22Originated%20in%20g%28%29%22%29%3B%0A%09%7D%20%0A%09public%20static%20void%20h%28%29%20throws%20MyException2%7B%0A%09%09System.out.println%28%22Throwing%20MyExcetion2%20from%20h%28%29%22%29%3B%0A%09%09throw%20new%20MyException2%28%22Originated%20in%20h%28%29%22%2C47%29%3B%0A%09%7D%20%0A%09%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09for%28int%20i%3D0%3Bi%3C5%3Bi++%29%7B%0A%09%09%09try%20%7B%0A%09%09%09%09f%28%29%3B%0A%09%09%09%7D%20catch%20%28MyException2%20e%29%20%7B%0A%09%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09%09e.printStackTrace%28%29%3B%0A%09%09%09%7D%0A%09%09%09try%20%7B%0A%09%09%09%09g%28%29%3B%0A%09%09%09%7D%20catch%20%28MyException2%20e%29%20%7B%0A%09%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09%09e.printStackTrace%28%29%3B%0A%09%09%09%7D%0A%09%09%09%0A%09%09%09try%20%7B%0A%09%09%09%09h%28%29%3B%0A%09%09%09%7D%20catch%20%28MyException2%20e%29%20%7B%0A%09%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09%09e.printStackTrace%28%29%3B%0A%09%09%09%09System.out.println%28%22e.val%3D%22+e.val%28%29%29%3B%0A%09%09%09%7D%0A%09%09%09System.out.println%28%22%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%22%29%3B%0A%09%09%7D%0A%09%7D%0A%7D%0A%60%60%60%0A%u9047%u5230%u4E00%u4E2A%u95EE%u9898%2C%20%u9884%u671F%u8DDF%u5B9E%u9645%u8F93%u51FA%u4E0D%u4E00%u6837.%20%u6709%u70B9%u8499%u4E86%2C%u521A%u53D1%u4E86%u4E2A%u5E16%u5B50%u95EE%2C%u8FD8%u5728%u7B49%u7B54%u6848...%0A%0A%23%23%u5F02%u5E38%u8BF4%u660E%0Ajava%u9F13%u52B1%u5927%u5BB6%u628A%u65B9%u6CD5%u80AF%u80FD%u4F1A%u629B%u51FA%u7684%u5F02%u5E38%u544A%u8BC9%u4F7F%u7528%u6B64%u65B9%u6CD5%u7684%u7A0B%u5E8F%u5458.%20%u8FD9%u79CD%u505A%u6CD5%u53EF%u4EE5%u8BA9%u8C03%u7528%u8005%u77E5%u9053%u8BE5%u65B9%u6CD5%u53EF%u80FD%u51FA%u73B0%u7684%u5F02%u5E38.%u5982%u679C%u53EF%u4EE5%u770B%u5230%u6E90%u7801%2C%u90A3%u4E48%u5728%u6E90%u7801%u4E2D%u53EF%u4EE5%u77E5%u9053%u65B9%u6CD5%u53EF%u80FD%u4F1A%u629B%u51FA%u7684%u5F02%u5E38.%20%u5982%u679C%u770B%u4E0D%u5230%u6E90%u7801%u5C82%u4E0D%u662F%u8499%u5708%u4E86.%20%u6240%u4EE5java%u63D0%u4F9B%u4E86%u4E00%u4E2Athrows%u5173%u952E%u5B57%2C%u8DDF%u5728%u65B9%u6CD5%u540D%u79F0%u5B9A%u4E49%u7684%u540E%u9762%2C%u8868%u793A%u8BE5%u65B9%u6CD5%u5185%u90E8%u53EF%u80FD%u4F1A%u629B%u51FA%u7684%u5F02%u5E38.%20%0A%20%u6BD4%u5982%60public%20void%20f%28%29%20throws%20Exception1%2CException2%2CException3...%20%60%u5982%u679C%u6CA1%u6709throws%u7684%u8BDD%2C%u8868%u793A%u51FA%u4E86%u4ECERuntimeException%u7EE7%u627F%u7684%u5F02%u5E38%2C%u5B83%u4E0D%u4F1A%u629B%u51FA%u4EFB%u4F55%u5176%u4ED6%u5F02%u5E38.%20%0A%20%u9700%u8981%u6CE8%u610F%u7684%u662F%2Cthrows%u629B%u51FA%u7684%u5F02%u5E38%u548C%u4EE3%u7801%u4E2D%u7684%u8BF4%u660E%u5FC5%u987B%u4E00%u81F4.%20%u4E5F%u5C31%u662F%u8BF4%2C%u8981%u4E48%u5904%u7406%u8FD9%u4E2A%u5F02%u5E38%2C%u8981%u4E48%u5728%u51FD%u6570%u58F0%u660E%u7684%u65F6%u5019%u629B%u51FA%u53BB.%20%u4F46%u662F%u53EF%u4EE5%u5728%u58F0%u660E%u65B9%u6CD5%u7684%u65F6%u5019throws%u5F02%u5E38%2C%u4F46%u5B9E%u9645%u4EE3%u7801%u4E0A%u4E0Dthrow.%20%u4E5F%u5C31%u662F%u9884%u5148%u5B9A%u4E49%u8FD9%u4E2A%u5F02%u5E38%2C%u4EE5%u540E%u4E0D%u9700%u8981%u518D%u4FEE%u6539%u8FD9%u91CC%u7684%u4EE3%u7801%u4E86.%20%u8FD9%u4E2A%u5728%u5B9A%u4E49%u62BD%u8C61%u7C7B%u548C%u63A5%u53E3%u7684%u65F6%u5019%u6BD4%u8F83%u5E38%u7528.%20%0A%0A%23%23%u6355%u83B7%u6240%u6709%u5F02%u5E38%0A%u53EF%u4EE5%u901A%u8FC7%u6355%u83B7%u5F02%u5E38%u7C7B%u578B%u7684%u57FA%u7C7B%u6027Exception%u6765%u7528%u4E00%u4E2Acatch%u5757%u6355%u83B7%u6240%u6709%u7684%u5F02%u5E38.%20%u4F46%u662F%u7528%u7684%u65F6%u5019%2C%u6700%u597D%u662F%u5C06%u5176%u653E%u5728%u6240%u6709catch%u5757%u7684%u6700%u540E.%20%u8FD9%u91CC%u5C31%u6D89%u53CA%u5230%u4E86java%u6355%u83B7%u5F02%u5E38%u7684%u987A%u5E8F%u4E86.%20java%u4F1A%u6309%u7167%u4EE3%u7801%u7684%u987A%u5E8F%2C%u8FDB%u5165%u7B2C%u4E00%u4E2A%u5339%u914D%u5230%u7684catch%u5757.%20%u6B63%u5E38%u6765%u8BF4%2C%u6211%u4EEC%u5E0C%u671B%u5F02%u5E38%u6355%u83B7%u7684%u8D8A%u7CBE%u786E%u8D8A%u597D.%20%u6240%u4EE5%u5728%u5199%u591A%u4E2Acatch%u5757%u7684%u65F6%u5019%2C%u4E00%u822C%u6309%u7167%u5F02%u5E38%u7684%22%u7531%u5C0F%u5230%u5927%22%u7684%u987A%u5E8F%u6765%u5199.%20%0A%0A**Exception**%0AException%u7C7B%u662F%u548C%u7F16%u7A0B%u76F8%u5173%u7684%u6240%u6709%u5F02%u5E38%u7C7B%u7684%u57FA%u7C7B.%20%u901A%u8FC7%u8FD9%u7C7B%u53EF%u4EE5%u8C03%u7528%u4ECEThrowable%u7C7B%u4E2D%u8C03%u7528%u7684%u4E00%u4E9B%u65B9%u6CD5%3A%0A-%20String%20getMessage%28%29%20%u8FD4%u56DE%u4E00%u4E2A%u7B80%u77ED%u63CF%u8FF0%u4FE1%u606F%0A-%20String%20getLocalizedMessage%28%29%0A-%20String%20toString%28%29%0A-%20void%20printStackTrace%28%29%20%u663E%u793A%u5F02%u5E38%u629B%u51FA%u5730%u70B9%u7684%u65B9%u6CD5%u8C03%u7528%u5E8F%u5217.%20%0A%0A%60%60%60java%0Apublic%20class%20ExceptionMethod%20%7B%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09try%20%7B%0A%09%09%09throw%20new%20Exception%28%22My%20exception%22%29%3B%0A%09%09%7D%20catch%20%28Exception%20e%29%20%7B%0A%09%09%09System.out.println%28%22Caught%20Exception%22%29%3B%0A%09%09%09System.out.println%28%22getMessage%28%29%3A%20%22+e.getMessage%28%29%29%3B%0A%09%09%09System.out.println%28%22getLocalMessage%28%29%3A%22+e.getLocalizedMessage%28%29%29%3B%0A%09%09%09System.out.println%28%22toString%28%29%3A%22+e.toString%28%29%29%3B%0A%09%09%09e.printStackTrace%28%29%3B%0A%09%09%7D%0A%09%7D%0A%7D/*output%3A%0ACaught%20Exception%0AgetMessage%28%29%3A%20My%20exception%0AgetLocalMessage%28%29%3AMy%20exception%0AtoString%28%29%3Ajava.lang.Exception%3A%20My%20exception%0Ajava.lang.Exception%3A%20My%20exception%0A%09at%20ch12_Exception.ExceptionMethod.main%28ExceptionMethod.java%3A6%29%0A*/%0A%60%60%60%0A%u5F02%u5E38%u7684%u4FE1%u606F%u5C31%u662F%u90A3%u4E48%u591A%2C%u800C%u6BCF%u4E2A%u65B9%u6CD5%u662F%u6307%u9009%u62E9%u4E0D%u540C%u7684%u90E8%u5206%u6765%u663E%u793A.%20%u5176%u5B9E%u6BCF%u4E2A%u65B9%u6CD5%u90FD%u662F%u524D%u4E00%u4E2A%u65B9%u6CD5%u7684%u8D85%u96C6.%20%0A%0A%23%23%23%u6808%u8F68%u8FF9%0AprintStackTrace%28%29%u65B9%u6CD5%u6240%u63D0%u4F9B%u7684%u4FE1%u606F%u53EF%u4EE5%u901A%u8FC7getStackTrace%28%29%u65B9%u6CD5%u76F4%u63A5%u8BBF%u95EE.%u8FD9%u4E2A%u65B9%u6CD5%u8FD4%u56DE%u4E00%u4E2A%u7531%u6808%u8F68%u8FF9%u4E2D%u7684%u5143%u7D20%u6240%u6784%u6210%u7684%u6570%u7EC4.%20%u5176%u4E2D%u6BCF%u4E2A%u5143%u7D20%u8868%u793A%u6808%u4E2D%u7684%u4E00%u5E27.%200%u8868%u793A%u6808%u9876%u5143%u7D20%2C%u4E5F%u5C31%u662F%u6700%u540E%u7684%u4E00%u4E2A%u65B9%u6CD5%u8C03%u7528.%u4E5F%u662FThrowable%u5BF9%u8C61%u88AB%u521B%u5EFA%u548C%u629B%u51FA%u7684%u5730%u65B9.%20%u6700%u540E%u4E00%u4E2A%u5143%u7D20%u662F%u7B2C%u4E00%u4E2A%u65B9%u6CD5%u8C03%u7528.%20%0A%60%60%60java%0Apublic%20class%20WhoCalled%20%7B%0A%09static%20void%20f%28%29%7B%0A%09%09try%20%7B%0A%09%09%09throw%20new%20Exception%28%29%3B%0A%09%09%7D%20catch%20%28Exception%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09for%28StackTraceElement%20ste%3Ae.getStackTrace%28%29%29%7B%0A%09%09%09%09System.out.println%28ste.getMethodName%28%29%29%3B%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%09static%20void%20g%28%29%7B%0A%09%09f%28%29%3B%0A%09%7D%0A%09static%20void%20h%28%29%7B%0A%09%09g%28%29%3B%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09f%28%29%3B%0A%09%09System.out.println%28%22--------------------%22%29%3B%0A%09%09g%28%29%3B%0A%09%09System.out.println%28%22--------------------%22%29%3B%0A%09%09h%28%29%3B%0A%09%09System.out.println%28%22--------------------%22%29%3B%0A%09%7D%0A%7D/*%0Af%0Amain%0A--------------------%0Af%0Ag%0Amain%0A--------------------%0Af%0Ag%0Ah%0Amain%0A--------------------%0A*/%0A%60%60%60%0A%0A%23%23%23%u91CD%u65B0%u629B%u51FA%u5F02%u5E38%0A%0A%u6709%u65F6%u5019%u6211%u4EEC%u9700%u8981%u5728%u6355%u83B7%u5F02%u5E38%u4E4B%u540E%u91CD%u65B0%u629B%u51FA%2C%u5C24%u5176%u662F%u4F7F%u7528Exception%u6355%u83B7%u6240%u6709%u5F02%u5E38%u7684%u65F6%u5019%2C%u65E2%u7136%u5DF2%u7ECF%u62FF%u5230%u4E86%u5F02%u5E38%u7684%u5F15%u7528%2C%u53EF%u4EE5%u76F4%u63A5%u518D%u628A%u5B83%u629B%u51FA%u53BB.%u91CD%u65B0%u629B%u51FA%u5F02%u5E38%u7ED9%u4E0A%u4E00%u7EA7%u73AF%u5883%u4E2D%u7684%u5F02%u5E38%u5904%u7406%u7A0B%u5E8F%2C%u540C%u4E00%u4E2Atry%u5757%u7684%u540E%u7EEDcatch%u5B50%u53E5%u5C06%u88AB%u5FFD%u7565.%20%u6240%u4EE5%u4E0A%u4E00%u7EA7%u73AF%u5883%u4E2D%u7684%u5F02%u5E38%u5904%u7406%u7A0B%u5E8F%u53EF%u4EE5%u5BF9%u8FD9%u4E2A%u5F02%u5E38%u5BF9%u8C61%u4E2D%u62FF%u5230%u6240%u6709%u4FE1%u606F.%20%u5982%u679C%u53EA%u662F%u628A%u5F53%u524D%u5BF9%u8C61%u91CD%u65B0%u629B%u51FA%2C%u90A3%u4E48%u4E0A%u4E00%u7EA7%u7684%u5F02%u5E38%u5904%u7406%u7A0B%u5E8F%u5F97%u5230%u5C06%u4F1A%u662F%u539F%u6765%u5F02%u5E38%u629B%u51FA%u70B9%u7684%u6808%u8C03%u7528%u4FE1%u606F.%20%u800C%u975E%u65B0%u629B%u51FA%u70B9%u7684%u4FE1%u606F.%20%u679C%u60F3%u8981%u66F4%u65B0%2C%u53EF%u4EE5%u8C03%u7528fillInStackTrace%28%29.%20%u8FD9%u5C06%u8FD4%u56DE%u4E00%u4E2AThrowable%u5BF9%u8C61%2C%u5B83%u662F%u901A%u8FC7%u5F53%u524D%u8C03%u7528%u6808%u4FE1%u606F%u586B%u5165%u539F%u6765%u90A3%u4E2A%u5F02%u5E38%u5BF9%u8C61%u800C%u5EFA%u7ACB%u7684.%20%0A%0A%60%60%60java%0Apublic%20class%20Rethrowing%20%7B%0A%09public%20static%20void%20f%28%29%20throws%20Exception%7B%0A%09%09System.out.println%28%22origination%20exception%20in%20f%28%29%22%29%3B%0A%09%09throw%20new%20Exception%28%22throw%20from%20f%28%29%22%29%3B%0A%09%7D%20%0A%09public%20static%20void%20g%28%29%20throws%20Exception%7B%0A%09%09try%7B%0A%09%09%09f%28%29%3B%0A%09%09%7Dcatch%20%28Exception%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.out.println%28%22Inside%20g%28%29%2Ce.printStackTrace%28%29%22%29%3B%0A%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%09throw%20e%3B%0A%09%09%7D%0A%09%7D%0A%09public%20static%20void%20h%28%29%20throws%20Exception%7B%0A%09%09try%20%7B%0A%09%09%09f%28%29%3B%0A%09%09%7D%20catch%20%28Exception%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.out.println%28%22Inside%20h%28%29%2Ce.printStackTrace%28%29%22%29%3B%0A%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%09throw%20%28Exception%29e.fillInStackTrace%28%29%3B%0A%09%09%7D%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09try%20%7B%0A%09%09%09g%28%29%3B%0A%09%09%7D%20catch%20%28Exception%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.out.println%28%22Main%3AprintStackTrace%28%29%22%29%3B%0A%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%7D%0A%09%09%0A%09%09try%20%7B%0A%09%09%09h%28%29%3B%0A%09%09%7D%20catch%20%28Exception%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.out.println%28%22Main%3AprintStackTrace%28%29%22%29%3B%0A%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%7D%0A%09%7D%0A%7D/*output%3A%0Aorigination%20exception%20in%20f%28%29%0AInside%20g%28%29%2Ce.printStackTrace%28%29%0Ajava.lang.Exception%3A%20throw%20from%20f%28%29%0A%09at%20ch12_Exception.Rethrowing.f%28Rethrowing.java%3A6%29%0A%09at%20ch12_Exception.Rethrowing.g%28Rethrowing.java%3A10%29%0A%09at%20ch12_Exception.Rethrowing.main%28Rethrowing.java%3A30%29%0AMain%3AprintStackTrace%28%29%0Ajava.lang.Exception%3A%20throw%20from%20f%28%29%0A%09at%20ch12_Exception.Rethrowing.f%28Rethrowing.java%3A6%29%0A%09at%20ch12_Exception.Rethrowing.g%28Rethrowing.java%3A10%29%0A%09at%20ch12_Exception.Rethrowing.main%28Rethrowing.java%3A30%29%0A%09%0A%09%0A%09%0Aorigination%20exception%20in%20f%28%29%0AInside%20h%28%29%2Ce.printStackTrace%28%29%0Ajava.lang.Exception%3A%20throw%20from%20f%28%29%0A%09at%20ch12_Exception.Rethrowing.f%28Rethrowing.java%3A6%29%0A%09at%20ch12_Exception.Rethrowing.h%28Rethrowing.java%3A20%29%0A%09at%20ch12_Exception.Rethrowing.main%28Rethrowing.java%3A38%29%0A%09%0AMain%3AprintStackTrace%28%29%0Ajava.lang.Exception%3A%20throw%20from%20f%28%29%0A%09at%20ch12_Exception.Rethrowing.h%28Rethrowing.java%3A25%29%0A%09at%20ch12_Exception.Rethrowing.main%28Rethrowing.java%3A38%29%0A*/%0A%60%60%60%0A%0A%u770B67%2C68%u884C%2C%u8FD9%u91CC%u662F%u6267%u884C%u4E86fillInStackTrace%28%29%u4E4B%u540E%u7684%2C%u5F02%u5E38%u629B%u51FA%u7684%u5730%u70B9.%20%0A%0A%0A%u5F53%u7136%2C%u53EF%u4EE5%u5728catch%u5757%u4E2D%u629B%u51FA%u53E6%u5916%u4E00%u4E2A%u5F02%u5E38.%20%0A%0A%60%60%60java%0Aclass%20OneException%20extends%20Exception%7B%0A%09public%20OneException%28String%20s%29%7B%0A%09%09super%28s%29%3B%0A%09%7D%0A%7D%0Aclass%20TwoException%20extends%20Exception%7B%0A%09public%20TwoException%28String%20s%29%7B%0A%09%09super%28s%29%3B%0A%09%7D%0A%7D%0A%0Apublic%20class%20ReThrowNew%20%7B%0A%09public%20static%20void%20f%28%29%20throws%20OneException%7B%0A%09%09System.out.println%28%22originating%20the%20exception%20in%20f%28%29%22%29%3B%0A%09%09throw%20new%20OneException%28%22throw%20from%20f%28%29%22%29%3B%0A%09%7D%20%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09try%20%7B%0A%09%09%09try%20%7B%0A%09%09%09%09f%28%29%3B%0A%09%09%09%7D%20catch%20%28OneException%20e%29%20%7B%0A%09%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09%09System.out.println%28%22Caught%20in%20inner%20try%2Ce.printStackTrace%28%29%22%29%3B%0A%09%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%09%09throw%20new%20TwoException%28%22from%20inner%20try%22%29%3B%0A%09%09%09%7D%0A%09%09%7D%20catch%20%28TwoException%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.out.println%28%22Caught%20in%20outer%20try%2Ce.printStackTrace%28%29%22%29%3B%0A%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%09%0A%09%09%7D%0A%09%7D%0A%7D/*output%3A%0Aoriginating%20the%20exception%20in%20f%28%29%0ACaught%20in%20inner%20try%2Ce.printStackTrace%28%29%0Ach12_Exception.OneException%3A%20throw%20from%20f%28%29%0A%09at%20ch12_Exception.ReThrowNew.f%28ReThrowNew.java%3A17%29%0A%09at%20ch12_Exception.ReThrowNew.main%28ReThrowNew.java%3A22%29%0ACaught%20in%20outer%20try%2Ce.printStackTrace%28%29%0Ach12_Exception.TwoException%3A%20from%20inner%20try%0A%09at%20ch12_Exception.ReThrowNew.main%28ReThrowNew.java%3A27%29%0A*/%0A%60%60%60%0A%u540E%u9762%u8FD9%u4E2A%u5F02%u5E38%2C%u53EA%u6709main%u65B9%u6CD5%u624D%u77E5%u9053%2Cf%28%29%u65B9%u6CD5%u5BF9%u5176%u4E00%u65E0%u6240%u77E5.%20%0A%0A%0A%0A%23%23Java%u6807%u51C6%u5F02%u5E38%0A%0A%20Throwable%u662Fjava%u4E2D%u4EFB%u4F55%u53EF%u4EE5%u4F5C%u4E3A%u5F02%u5E38%u88AB%u629B%u51FA%u7684%u7C7B.%28%u6CE8%u610F%2C%u4E0D%u662FException%2C%u4E0D%u662FException%2C%u4E0D%u662FException%29%20Throwable%0A%20%u5BF9%u8C61%u53EF%u4EE5%u5206%u4E3A%u4E24%u79CD%u7C7B%u578B%3AError%u7528%u6765%u8868%u793A%u7F16%u8BD1%u65F6%u548C%u7CFB%u7EDF%u9519%u8BEF.%20Exception%u662F%u53EF%u88AB%u629B%u51FA%u7684%u57FA%u672C%u7C7B%u578B.%20%20%u5728java%u7C7B%u5E93%2C%u7528%u6237%u65B9%u6CD5%2C%u4EE5%u53CA%u8FD0%u884C%u65F6%u95EE%u9898%2C%u90FD%u53EF%u80FD%u4F1A%u629B%u51FAException.%20%u8FD9%u4E5F%u662Fjava%u7A0B%u5E8F%u5458%u6700%u5173%u5FC3%u7684%u95EE%u9898.%20%0A%0Ajava%u7684%u5F02%u5E38%u7C7B%u578B%u5176%u5B9E%u90FD%u5F88%u7B80%u5355%2C%u4E3B%u8981%u662F%u9760%u540D%u5B57.%20java%u5F02%u5E38%u7684%u6982%u5FF5%2C%u662F%u4F7F%u7528%u540D%u79F0%u8868%u793A%u53D1%u751F%u7684%u95EE%u9898.%20%u4E5F%u5C31%u662F%u901A%u8FC7%u540D%u5B57%u5C31%u5927%u6982%u53EF%u4EE5%u77E5%u9053%u53D1%u751F%u4E86%u4EC0%u4E48%u95EE%u9898.%20%u6240%u4EE5%u5728%u81EA%u5B9A%u4E49%u5F02%u5E38%u7684%u65F6%u5019%u4E5F%u8981%u6CE8%u610F%2C%u4E0D%u8981%u8D77Exception1%u8FD9%u79CD%u6076%u5FC3%u7684%u540D%u5B57.%20%0A%0A%u6CE8%u610F%u4E00%u4E2A%u7279%u4F8B%2CRuntimeException.%20%u8FD0%u884C%u65F6%u5F02%u5E38%u5F88%u591A%2C%u6BD4%u5982%u7A7A%u6307%u9488%u9519%2C%u8FD9%u4E9B%u9519%u8BEF%u90FD%u7EE7%u627F%u81EARuntimeException.%20%u4F1A%u88ABJVM%u81EA%u52A8%u629B%u51FA.%20%u4ED6%u4EEC%u4E5F%u88AB%u79F0%u4E3A%u662F%u4E0D%u53D7%u68C0%u67E5%u7684%u5F02%u5E38.%20%u5982%u679C%u6CA1%u6709%u5BF9RuntimeException%u5F02%u5E38%u8FDB%u884C%u6355%u83B7%2C%u90A3%u4E48%2C%u5B83%u5C31%u4F1A%u7A7F%u8D8A%u6240%u6709%u65B9%u6CD5%2C%u76F4%u5230main%u65B9%u6CD5%u7136%u540E%u629B%u51FA%2C%u7136%u540E%u4F1A%u8C03%u7528printStackStrace%28%29.%20%u5BF9%u4E8E%u8FD9%u79CD%u5F02%u5E38%2C%u4E0D%u9700%u8981%u8BF4%u660E%2C%u5176%u8F93%u51FA%u62A5%u544A%u5C31%u76F4%u63A5%u5230%u4E86System.err.%20%0A%0A%23%23%u4F7F%u7528finally%0A%u4E00%u822C%u629B%u51FA%u5F02%u5E38%u4E4B%u540E%2C%u65B9%u6CD5%u5C31%u4F1A%u88AB%u7EC8%u6B62%2C%u5728%u5F02%u5E38%u4E4B%u540E%u7684%u4EE3%u7801%u5C31%u6CA1%u6709%u529E%u6CD5%u6267%u884C%u4E86.%20%u4F46%u662F%u6709%u4E00%u4E9B%u4EE3%u7801%2C%u6BD4%u5982%u5173%u95ED%u6570%u636E%u5E93%u8FDE%u63A5%2C%u5173%u95ED%u6D41%u7B49%2C%u5982%u679C%u5728%u6267%u884C%u4E4B%u524D%u629B%u51FA%u4E86%u5F02%u5E38%2C%u90A3%u5C31%u60B2%u5267%u4E86.%20%u6240%u4EE5%u4E00%u4E9B%u51FA%u4E86%u5185%u5B58%u56DE%u6536%u4E4B%u5916%u7684%u6E05%u7406%u52A8%u4F5C%2C%u662F%u65E0%u8BBA%u5F02%u5E38%u662F%u5426%u53D1%u751F%u90FD%u8981%u6267%u884C%u7684.%20%u600E%u4E48%u529E%u5462%2Cjava%u63D0%u4F9B%u4E86finally%u5B50%u53E5.%20%0A%0A%0A%u5173%u4E8Efinally%u5B50%u53E5%2C%u53EA%u9700%u8981%u8BB0%u4F4F%u4E00%u53E5%u8BDD%2Cfinally%u5B50%u53E5%u603B%u4F1A%u88AB%u6267%u884C.%20%u65E0%u8BBA%u662F%u5426%u6709%u5F02%u5E38%u90FD%u4F1A%u6267%u884C.%20%u90A3%u4E48%u5982%u679C%u7A0B%u5E8F%u5728try%u5757%u4E2Dreturn%u4E86%u5462%3F%0A%60%60%60java%0Apublic%20class%20FianllyTest%20%7B%0A%09public%20static%20int%20f%28int%20val%29%7B%0A%09%09try%20%7B%0A%09%09%09System.out.println%28%22111%22%29%3B%0A%09%09%09if%28val%3D%3D1%29%20return%201%3B%0A%09%09%09else%20if%28val%3D%3D2%29%20return%202%3B%0A%09%09%09else%20return%2023333%3B%0A%09%09%7D%20finally%20%7B%0A%09%09%09//%20TODO%3A%20handle%20finally%20clause%0A%09%09%09System.out.println%28%22I%20am%20in%20finally%20block%22%29%3B%0A%09%09%7D%0A%09%7D%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09System.out.println%28f%2810%29%29%3B%0A%09%09System.out.println%28f%281%29%29%3B%0A%09%09System.out.println%28f%282%29%29%3B%0A%09%09%0A%09%7D%0A%7D/*output%3A%0A111%0AI%20am%20in%20finally%20block%0A23333%0A111%0AI%20am%20in%20finally%20block%0A1%0A111%0AI%20am%20in%20finally%20block%0A2%0A*/%0A%60%60%60%0A%0A%u770B%u8FD9%u4E2A%u4F8B%u5B50%u5C31%u660E%u767D%u4E86%2Cfinally%u5B50%u53E5%u603B%u4F1A%u88AB%u6267%u884C%2C%u5373%u4F7Ftry%u5757%u4E2D%u5DF2%u7ECFreturn%u4E86%2C%u5B83%u8FD8%u662F%u4F1A%u6267%u884C%u7684.%0A%0A%0A%0A**%u5F02%u5E38%u4E22%u5931**%0A%60%60%60java%0A%0Aclass%20VeryImportantException%20extends%20Exception%7B%0A%09public%20String%20toString%28%29%7B%0A%09%09return%20%22A%20very%20important%20exception%22%3B%0A%09%7D%0A%7D%0A%0Aclass%20HoHumException%20extends%20Exception%7B%0A%09public%20String%20toString%28%29%7B%0A%09%09return%20%22a%20trival%20exception%22%3B%0A%09%7D%0A%7D%0Apublic%20class%20LostMessage%20%7B%0A%09void%20f%28%29%20throws%20VeryImportantException%7B%0A%09%09throw%20new%20VeryImportantException%28%29%3B%0A%09%7D%0A%09void%20dispose%28%29throws%20HoHumException%7B%0A%09%09throw%20new%20HoHumException%28%29%3B%0A%09%7D%20%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09try%7B%0A%09%09%09LostMessage%20lm%20%3D%20new%20LostMessage%28%29%3B%0A%09%09%09try%7B%0A%09%09%09%09lm.f%28%29%3B%0A%09%09%09%7Dfinally%20%7B%0A%09%09%09%09lm.dispose%28%29%3B%0A%09%09%09%7D%0A%09%09%7Dcatch%20%28Exception%20e%29%20%7B%0A%09%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09%09System.out.println%28e%29%3B%0A%09%09%09%7D%0A%09%09%0A%09%7D%0A%7D%0A%60%60%60%0A%0A%u770B%u8FD9%u4E48%u4E00%u4E2A%u4F8B%u5B50%2CVeryImportantException%u4E0D%u89C1%u4E86.%20%u53EA%u6355%u83B7%u5230%u4E86HoHumException.%20%u8FD9%u79CD%u60C5%u51B5%u662F%u4E0D%u5E94%u8BE5%u51FA%u73B0%u7684%2C%u6309%u7167%u5267%u672C%u6765%u8BF4%2C%u8FD9%u79CD%u60C5%u51B5%u662F%u4E0D%u5E94%u8BE5%u51FA%u73B0%u7684.%u6309%u7167C++%u7684%u601D%u8DEF%2C%u524D%u4E00%u4E2A%u5F02%u5E38%u8FD8%u6CA1%u6709%u5904%u7406%u5C31%u629B%u51FA%u4E0B%u4E00%u4E2A%u5F02%u5E38%2C%u8FD9%u662F%u4E0D%u5E94%u8BE5%u7684.%20%u4F46%u662Fjava%u5E76%u6CA1%u6709%u5BF9%u5176%u505A%u5F88%u597D%u7684%u68C0%u67E5.%20%u5728%u4F7F%u7528try-finall%u7ED3%u6784%u7684%u65F6%u5019%u5F88%u6709%u53EF%u80FD%u4F1A%u51FA%u73B0%u8FD9%u79CD%u60C5%u51B5.%20%u6240%u4EE5%u6682%u65F6%2C%u6216%u8BB8%u6211%u4EEC%u53EA%u80FD%u9760%u826F%u597D%u7684%u7F16%u7A0B%u4E60%u60EF%u6765%u89E3%u51B3%u5B83.%20%u5C3D%u91CF%u4F7F%u7528try-catch-finally%u7ED3%u6784.%0A%60%60%60java%0Atry%7B%0A%09%09%09%09lm.f%28%29%3B%0A%09%09%09%7Dcatch%20%28Exception%20e%29%20%7B%0A%09%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09%09System.out.println%28e%29%3B%0A%09%09%09%7D%0A%09%09%09finally%20%7B%0A%09%09%09%09lm.dispose%28%29%3B%0A%09%09%09%7D%0A%60%60%60%0A%0A%23%23%u5F02%u5E38%u7684%u9650%u5236%0A%u6240%u8C13%u5F02%u5E38%u9650%u5236%u5C31%u662F%2C%u5F53%u8986%u76D6%u65B9%u6CD5%u7684%u65F6%u5019%2C%u53EA%u80FD%u629B%u51FA%u57FA%u7C7B%u65B9%u6CD5%u7684%u5F02%u5E38%u8BF4%u660E%u4E2D%u5217%u51FA%u6765%u7684%u90A3%u4E9B%u5F02%u5E38.%u8FD9%u4E2A%u9650%u5236%u5F88%u6709%u7528%2C%u5F53%u57FA%u7C7B%u7684%u4EE3%u7801%u5E94%u7528%u5230%u5176%u6D3E%u751F%u7C7B%u7684%u65F6%u5019%2C%u4E00%u6837%u80FD%u591F%u5DE5%u4F5C.%20%0A%60%60%60java%0A//%3A%20exceptions/StormyInning.java%20%0A//Overridden%20methods%20may%20throw%20only%20the%20exceptions%20%0A//specified%20in%20their%20base-class%20versions%2C%20or%20exceptions%20%0A//derived%20from%20the%20base-class%20exceptions.%20%0A%0Aclass%20BaseballException%20extends%20Exception%20%7B%0A%7D%0A%0Aclass%20Foul%20extends%20BaseballException%20%7B%0A%7D%0A%0Aclass%20Strike%20extends%20BaseballException%20%7B%0A%7D%0A%0Aabstract%20class%20Inning%20%7B%0A%09public%20Inning%28%29%20throws%20BaseballException%20%7B%0A%09%7D%0A%0A%09public%20void%20event%28%29%20throws%20BaseballException%20%7B%0A%09%09//%20Doesn%u2019t%20actually%20have%20to%20throw%20anything%0A%09%7D%0A%0A%09public%20abstract%20void%20atBat%28%29%20throws%20Strike%2C%20Foul%3B%0A%0A%09public%20void%20walk%28%29%20%7B%0A%09%7D%20//%20Throws%20no%20checked%20exceptions%0A%7D%0A%0Aclass%20StormException%20extends%20Exception%20%7B%0A%7D%0A%0Aclass%20RainedOut%20extends%20StormException%20%7B%0A%7D%0A%0Aclass%20PopFoul%20extends%20Foul%20%7B%0A%7D%0A%0Ainterface%20Storm%20%7B%0A%09public%20void%20event%28%29%20throws%20RainedOut%3B%0A%0A%09public%20void%20rainHard%28%29%20throws%20RainedOut%3B%0A%7D%0A%0Apublic%20class%20StormyInning%20extends%20Inning%20implements%20Storm%20%7B%0A%09//%20OK%20to%20add%20new%20exceptions%20for%20constructors%2C%20but%20you%0A%09//%20must%20deal%20with%20the%20base%20constructor%20exceptions%3A%0A%09public%20StormyInning%28%29%20throws%20RainedOut%2C%20BaseballException%20%7B%0A%09%7D%0A%0A%09public%20StormyInning%28String%20s%29%20throws%20Foul%2C%20BaseballException%20%7B%0A%09%7D%0A%0A%09//%20Regular%20methods%20must%20conform%20to%20base%20class%3A%0A%09//%20%21%20void%20walk%28%29%20throws%20PopFoul%20%7B%7D%20//Compile%20error%0A%09//%20Interface%20CANNOT%20add%20exceptions%20to%20existing%0A%09//%20methods%20from%20the%20base%20class%3A%0A%09//%20%21%20public%20void%20event%28%29%20throws%20RainedOut%20%7B%7D%0A%09//%20If%20the%20method%20doesn%u2019t%20already%20exist%20in%20the%0A%09//%20base%20class%2C%20the%20exception%20is%20OK%3A%0A%09public%20void%20rainHard%28%29%20throws%20RainedOut%20%7B%0A%09%7D%0A%0A%09//%20You%20can%20choose%20to%20not%20throw%20any%20exceptions%2C%0A%09//%20even%20if%20the%20base%20version%20does%3A%0A%09public%20void%20event%28%29%20%7B%0A%09%7D%0A%0A%09//%20Overridden%20methods%20can%20throw%20inherited%20exceptions%3A%0A%09public%20void%20atBat%28%29%20throws%20PopFoul%20%7B%0A%09%7D%0A%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09try%20%7B%0A%09%09%09StormyInning%20si%20%3D%20new%20StormyInning%28%29%3B%0A%09%09%09si.atBat%28%29%3B%0A%09%09%7D%20catch%20%28PopFoul%20e%29%20%7B%0A%09%09%09System.out.println%28%22Pop%20foul%22%29%3B%0A%09%09%7D%20catch%20%28RainedOut%20e%29%20%7B%0A%09%09%09System.out.println%28%22Rained%20out%22%29%3B%0A%09%09%7D%20catch%20%28BaseballException%20e%29%20%7B%0A%09%09%09System.out.println%28%22Generic%20baseball%20exception%22%29%3B%0A%09%09%7D%0A%09%09//%20Strike%20not%20thrown%20in%20derived%20version.%0A%09%09try%20%7B%0A%09%09%09//%20What%20happens%20if%20you%20upcast%3F%0A%09%09%09Inning%20i%20%3D%20new%20StormyInning%28%29%3B%0A%09%09%09i.atBat%28%29%3B%0A%09%09%09//%20You%20must%20catch%20the%20exceptions%20from%20the%0A%09%09%09//%20base-class%20version%20of%20the%20method%3A%0A%09%09%7D%20catch%20%28Strike%20e%29%20%7B%0A%09%09%09System.out.println%28%22Strike%22%29%3B%0A%09%09%7D%20catch%20%28Foul%20e%29%20%7B%0A%09%09%09System.out.println%28%22Foul%22%29%3B%0A%09%09%7D%20catch%20%28RainedOut%20e%29%20%7B%0A%09%09%09System.out.println%28%22Rained%20out%22%29%3B%0A%09%09%7D%20catch%20%28BaseballException%20e%29%20%7B%0A%09%09%09System.out.println%28%22Generic%20baseball%20exception%22%29%3B%0A%09%09%7D%0A%09%7D%0A%7D%20///%20%3A%7E%0A%0A%60%60%60%20%0A%0A%u770B%u57C3%u5927%u7237%u7684%u4E66%u5B66%u4E86%u4E0D%u5C11%u5355%u8BCD...%0A%0A-%20%u5728Inning%u7C7B%u4E2D%2C%u6784%u9020%u5668%u548Cevent%28%29%u65B9%u6CD5%u90FD%u58F0%u660E%u8981%u629B%u51FA%u5F02%u5E38%2C%u5B9E%u9645%u4E0A%u5374%u6CA1%u6709%u629B%u51FA.%20%u8FD9%u79CD%u65B9%u5F0F%u53EF%u4EE5%u5F3A%u5236%u8BA9%u7528%u6237%u53BB%u6355%u83B7%u53EF%u80FD%u5728%u91CD%u5199%u540E%u589E%u52A0%u7684%u5F02%u5E38.%u5BF9%u4E8E%u62BD%u8C61%u65B9%u6CD5%2C%u540C%u6837%u9002%u7528.%20%0A-%20Storm%u63A5%u53E3%u4E2D%2C%u5305%u542B%u4E86%u4E00%u4E2AInning%u5B9A%u4E49%u7684event%28%29%u65B9%u6CD5%u548C%u4E0D%u518DInning%u4E2D%u5B9A%u4E49%u7684rainHard%u65B9%u6CD5.%20%u8FD9%u4E24%u4E2A%u65B9%u6CD5%u90FD%u629B%u51FA%u65B0%u7684%u5F02%u5E38%2CRainedOut.%20%u5982%u679C%u6269%u5C55%u7C7B%u4E2D%u7EE7%u627F%u4E86Inning%u7C7B%u53C8%u5B9E%u73B0%u4E86Storm%u63A5%u53E3%2C%u90A3%u4E48%u5728%u6269%u5C55%u7C7B%u4E2D%u5C31%u4E0D%u80FD%u6539%u53D8%u57FA%u7C7B%u7684throws%u7684%u5F02%u5E38%u5217%u8868.%20%u6240%u4EE5%u5728%u6269%u5C55%u7C7B%u4E2D%2C%u53EF%u4EE5%u770B%u5230event%28%29%u65B9%u6CD5%u6CA1%u6709%u629B%u51FA%u5F02%u5E38.%20%0A-%20%u5982%u679C%u63A5%u53E3%u4E2D%u5B9A%u4E49%u7684%u65B9%u6CD5%u6CA1%u6709%u548C%u57FA%u7C7B%u4E2D%u7684%u91CD%u540D%2C%u6BD4%u5982rainHard%28%29%2C%u90A3%u4E48%u6B64%u65B9%u6CD5%2C%u629B%u51FA%u4EC0%u4E48%u6837%u7684%u5F02%u5E38%u90FD%u65E0%u6240%u8C13.%20%0A-%20%u5F02%u5E38%u9650%u5236%u5BF9%u6784%u9020%u5668%u4E0D%u8D77%u4F5C%u7528.%20%u4F46%u662F%2C%u56E0%u4E3A%u57FA%u7C7B%u6784%u9020%u5668%u5728%u6269%u5C55%u7C7B%u4E2D%u5FC5%u987B%u88AB%u8C03%u7528.%20%u6240%u4EE5%u6D3E%u751F%u7C7B%u7684%u6784%u9020%u5668%u5FC5%u987B%u629B%u51FA%u5305%u542B%u57FA%u7C7B%u6784%u9020%u5668%u6240%u629B%u51FA%u7684%u5F02%u5E38%0A-%20walk%28%29%u65B9%u6CD5%u4E0D%u80FD%u901A%u8FC7%u7F16%u8BD1%2C%u662F%u56E0%u4E3A%u5728%u57FA%u7C7B%u4E2D%u5B83%u5E76%u6CA1%u629B%u51FA%u5F02%u5E38%2C%u4F46%u662F%u5728%u6269%u5C55%u7C7B%u4E2D%u629B%u4E86.%20%u8FD9%u4E2A%u662F%u4E0D%u53EF%u4EE5%u7684.%20%0A-%20event%28%29%u65B9%u6CD5%u6CA1%u6709%u629B%u51FA%u5F02%u5E38%2CatBat%28%29%u65B9%u6CD5%u629B%u51FA%u7684%u5F02%u5E38%u662F%u57FA%u7C7B%u5F02%u5E38%u8BF4%u660E%u7684%u5B50%u96C6%2C%u8FD9%u4E2A%u90FD%u662F%u5141%u8BB8%u7684%2C%u56E0%u4E3A%u5728%u5411%u4E0A%u8F6C%u578B%u4E4B%u540E%2C%u5E76%u4E0D%u4F1A%u9020%u6210%u57FA%u7C7B%u65B9%u6CD5%u5931%u6548.%20%0A-%20%u5173%u4E8Emain%28%29%u65B9%u6CD5%2C%u6CE8%u610F%2C%u5728%u5411%u4E0A%u8F6C%u578B%u4E4B%u540E%2C%u7F16%u8BD1%u5668%u4F1A%u8981%u6C42%u6309%u7167%u57FA%u7C7B%u6240%u629B%u51FA%u7684%u5F02%u5E38%u6765%u5904%u7406.%20%0A%0A%u6CE8%u610F%2C%u5728%u7EE7%u627F%u7684%u8FC7%u7A0B%u4E2D%2C%u7F16%u8BD1%u5668%u4F1A%u8981%u6C42%u5BF9%u5F02%u5E38%u505A%u5F3A%u5236%u8BF4%u660E.%20%u4F46%u662F%u8FD9%u5E76%u4E0D%u8868%u793A%u5F02%u5E38%u5217%u8868%u672C%u8EAB%u5C5E%u4E8E%u65B9%u6CD5%u7C7B%u578B%u7684%u4E00%u90E8%u5206.%20%u65B9%u6CD5%u7B7E%u540D%u4EC5%u5305%u62EC%u65B9%u6CD5%u540D%u548C%u5F62%u53C2%u5217%u8868.%20%u4E0A%u9762balabalabala%u90A3%u4E48%u591A%2C%u5176%u5B9E%u5C31%u8BF4%u660E%u4E86%u4E00%u4E2A%u95EE%u9898%2C%u5B50%u7C7B%u7684%u5F02%u5E38%u8BF4%u660E%u5217%u8868%u5FC5%u987B%u8981%22%u5C0F%u4E8E%u7B49%u4E8E%22%u57FA%u7C7B%u7684.%20%u7ED3%u5408%u4E4B%u524D%u8BF4%u8FC7%2C%u65B9%u6CD5%u53EF%u4EE5throws%u5F02%u5E38%u4F46%u662F%u5728%u65B9%u6CD5%u4F53%u5185%u4E0D%u629B%u51FA.%20%u90A3%u4E48%u8FD9%u79CD%u9650%u5236%u5C31%u4F7F%u5F97%u7A0B%u5E8F%u66F4%u52A0%u5065%u58EE.%20%0A%0A%0A%23%23%u6784%u9020%u5668%0A%u5F02%u5E38%u53D1%u751F%u7684%u65F6%u5019%2C%u6700%u9EBB%u70E6%u7684%u4E8B%u60C5%u662F%u8BE5%u6E05%u7406%u7684%u4E1C%u897F%u662F%u5426%u90FD%u6E05%u7406%u4E86.%20%u7EDD%u5927%u591A%u6570%u60C5%u51B5%u4E0B%2C%20%u98DE%u673A%u5728%u8D77%u98DE%u548C%u964D%u843D%u7684%u65F6%u5019%u6700%u5371%u9669%2C%u5BF9%u8C61%u5728%u751F%u6210%u548C%u9500%u6BC1%u7684%u65F6%u5019%u6700%u5371%u9669.%20%u56E0%u4E3A%u8FD9%u90FD%u4E0D%u662F%u7A33%u5B9A%u72B6%u6001.%20%u5982%u679C%u6784%u9020%u5668%u5185%u90E8%u51FA%u73B0%u4E86%u5F02%u5E38%2C%u6E05%u7406%u884C%u4E3A%u6216%u8BB8%u5C31%u4E0D%u80FD%u6B63%u5E38%u5DE5%u4F5C%u4E86.%20%u4F7F%u7528try-catch-finally%u7ED3%u6784%u90FD%u53EF%u4EE5%u5B89%u5168%u7684%u89E3%u51B3%u8FD9%u4E2A%u95EE%u9898.%20%u4F46%u662F%u5982%u679C%u662F%u6784%u9020%u5668%u5C31%u9EBB%u70E6%u4E86.%u56E0%u4E3Afinally%u603B%u4F1A%u6267%u884C%2C%u5982%u679C%u5728%u6784%u9020%u5668%u4E2D%u4F7F%u7528finally%u5757%u6765%u8FDB%u884C%u6E05%u7406%u7684%u8BDD%2C%u90A3%u4E48%u521B%u5EFA%u7684%u5BF9%u8C61%u5728%u6784%u9020%u5668%u4E2D%u5C31%u88AB%u6E05%u7406%u4E86.%20%u548B%u6574%3F%3F%3F%0A%0A%60%60%60java%0Apublic%20class%20InputFile%20%7B%0A%09private%20BufferedReader%20in%3B%0A%09public%20InputFile%28String%20filename%29%20throws%20Exception%7B%0A%09%09try%7B%0A%09%09%09in%20%3D%20new%20BufferedReader%28new%20FileReader%28filename%29%29%3B%0A%09%09%7Dcatch%20%28FileNotFoundException%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.out.println%28%22can%20not%20open%20the%20fire%22+filename%29%3B%0A%09%09%09throw%20e%3B%0A%09%09%7Dcatch%20%28Exception%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09try%7B%0A%09%09%09%09in.close%28%29%3B%0A%09%09%09%7Dcatch%20%28IOException%20e2%29%20%7B%0A%09%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09%09System.out.println%28%22in.close%28%29%20unsuccessful%22%29%3B%0A%09%09%09%7D%0A%09%09%09throw%20e%3B%0A%09%09%7Dfinally%20%7B%0A%09%09%09//%u6CA1%u6709%u64CD%u4F5C%0A%09%09%7D%0A%09%7D%0A%09public%20String%20getLine%28%29%7B%0A%09%09String%20s%3B%0A%09%09try%7B%0A%09%09%09s%20%3D%20in.readLine%28%29%3B%0A%09%09%7Dcatch%20%28IOException%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09throw%20new%20RuntimeException%28%22readline%28%29%20failed%22%29%3B%0A%09%09%7D%0A%09%09return%20s%3B%0A%09%7D%0A%09public%20void%20dispose%28%29%7B%0A%09%09try%20%7B%0A%09%09%09in.close%28%29%3B%0A%09%09%09System.out.println%28%22close%20success%22%29%3B%0A%09%09%7D%20catch%20%28IOException%20e2%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09throw%20new%20RuntimeException%28%22in.close%28%29%20failed%22%29%3B%0A%09%09%7D%0A%09%7D%0A%7D%0A%60%60%60%0A%0A%u6CE8%u610F3-22%u884C%u7684%u6784%u9020%u5668.%20%u5982%u679CFileReader%u7684%u6784%u9020%u5668%u5B9E%u767D%u4E86%2C%u629B%u51FAFileNotFoundException%u5F02%u5E38%2C%u5BF9%u4E8E%u8FD9%u4E2A%u5F02%u5E38%2C%u4E0D%u9700%u8981%u5173%u95ED%u6587%u4EF6%2C%u56E0%u4E3A%u6587%u4EF6%u8FD8%u6CA1%u6709%u6253%u5F00.%20%u800C%u5176%u4ED6%u6355%u83B7%u5230%u5F02%u5E38%u7684catch%u8BED%u53E5%u5C31%u9700%u8981%u5173%u95ED%u6587%u4EF6%u4E86.%20%u505A%u5B8C%u672C%u5730%u5904%u7406%u4E4B%u540E%2C%u5F02%u5E38%u88AB%u91CD%u65B0%u629B%u51FA%2C%u5BF9%u4E8E%u6784%u9020%u5668%u800C%u8A00%2C%u8FD9%u662F%u5F88%u5408%u9002%u7684%u505A%u6CD5.%20%u56E0%u4E3A%u8FD9%u6837%u4E0D%u4F1A%u8BEF%u5BFC%u8C03%u7528%u8005%2C%u8BA9%u4ED6%u8BA4%u4E3A%u5DF2%u7ECF%u6784%u9020%u6210%u529F%u4E86.%20%0A%u5BF9%u4E8E%u6784%u9020%u9636%u6BB5%u5C31%u53EF%u80FD%u4F1A%u629B%u51FA%u5F02%u5E38%u7684%u7C7B%2C%u6700%u5B89%u5168%u7684%u505A%u6CD5%u662F%u4F7F%u7528%u5D4C%u5957%u7684try%u5B50%u53E5%u6765%u5904%u7406.%20%0A%60%60%60java%0Apublic%20class%20Cleanup%20%7B%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09%09try%20%7B%0A%09%09%09InputFile%20in%20%3D%20new%20InputFile%28%22Cleanup.java%22%29%3B%0A%09%09%09try%7B%0A%09%09%09%09String%20s%3B%0A%09%09%09%09int%20i%20%3D1%3B%0A%09%09%09%09while%28%28s%3Din.getLine%28%29%29%21%3Dnull%29%7B%0A%09%09%09%09%09//...%0A%09%09%09%09%7D%0A%09%09%09%7Dcatch%20%28Exception%20e%29%20%7B%0A%09%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09%09System.out.println%28%22caught%20exception%20in%20main%22%29%3B%0A%09%09%09%09e.printStackTrace%28System.out%29%3B%0A%09%09%09%7Dfinally%7B%0A%09%09%09%09in.dispose%28%29%3B%0A%09%09%09%7D%0A%09%09%7D%20catch%20%28Exception%20e%29%20%7B%0A%09%09%09//%20TODO%3A%20handle%20exception%0A%09%09%09System.out.println%28%22input%20file%20construction%20failed%22%29%3B%0A%09%09%7D%0A%09%7D%0A%7D%0A%60%60%60%0A%u7B2C4%u884C%u4EE3%u7801%2C%u5982%u679C%u6784%u9020%u5B9E%u767D%u76F4%u63A5%u4F1A%u8FDB%u5165%u81EA%u5DF1%u7684catch%u8BED%u53E5%u5757%2C%u4E5F%u5C31%u662F18%u884C.%20%u8FD9%u6837%u7684%u8BDD%2Cdispose%28%29%u8BED%u53E5%u4E5F%u4E0D%u4F1A%u88AB%u8C03%u7528.%20%u800C%u5982%u679C%u6784%u9020%u6210%u529F%u4F1A%u8FDB%u5165%u5185%u5C42try%u5757%u6267%u884C.%20%u5728%u8FD9%u79CD%u65B9%u6CD5%u4E2D%2Cfinally%u5B50%u53E5%u5728%u6784%u9020%u5931%u8D25%u7684%u65F6%u5019%u4E0D%u4F1A%u88AB%u6267%u884C.%20%u800C%u6784%u9020%u6210%u529F%u7684%u65F6%u5019%u603B%u662F%u4F1A%u88AB%u6267%u884C.%20%u4F46%u662F%2C%u8FD9%u79CD%u529E%u6CD5%u867D%u7136%u80FD%u89E3%u51B3%u95EE%u9898%2C%u4F46%u662F%u5728%u7EDD%u5927%u90E8%u5206%u60C5%u51B5%u4E0B%2C%u8FD8%u662F%u9700%u8981%u6E05%u7406%u5BF9%u8C61%u7684%u65F6%u5019%2C%u7ACB%u5373%u8FDB%u5165finally%u5757%u4E2D.%20%0A%0A%60%60%60java%0Aclass%20NeedCleanup%20%7B%0A%09private%20static%20long%20counter%20%3D%201%3B%0A%09private%20final%20long%20id%20%3D%20counter++%3B%0A%0A%09public%20void%20dispose%28%29%20%7B%0A%09%09System.out.println%28%22need%20cleanup%20%22%20+%20id%20+%20%22%20disposed%22%29%3B%0A%09%7D%0A%7D%0A%0Aclass%20ConstructionException%20extends%20Exception%20%7B%0A%0A%7D%0A%0Aclass%20NeedCleanup2%20extends%20NeedCleanup%20%7B%0A%09public%20NeedCleanup2%28%29%20throws%20ConstructionException%20%7B%0A%0A%09%7D%0A%7D%0A%0Apublic%20class%20CleanupIdiom%20%7B%0A%09public%20static%20void%20main%28String%5B%5D%20args%29%20%7B%0A%09//section1%0A%09%09NeedCleanup%20nc1%20%3D%20new%20NeedCleanup%28%29%3B%0A%09%09try%20%7B%0A%0A%09%09%7D%20finally%20%7B%0A%09%09%09nc1.dispose%28%29%3B%0A%09%09%7D%0A%09//section2%0A%09%09NeedCleanup%20nc2%20%3D%20new%20NeedCleanup%28%29%3B%0A%09%09NeedCleanup%20nc3%20%3D%20new%20NeedCleanup%28%29%3B%0A%09%09try%20%7B%0A%0A%09%09%7D%20finally%20%7B%0A%09%09%09nc3.dispose%28%29%3B%0A%09%09%09nc2.dispose%28%29%3B%0A%09%09%7D%0A%09//section3%0A%09%09try%20%7B%0A%09%09%09NeedCleanup2%20nc4%20%3D%20new%20NeedCleanup2%28%29%3B%0A%09%09%09try%20%7B%0A%09%09%09%09NeedCleanup2%20nc5%20%3D%20new%20NeedCleanup2%28%29%3B%0A%09%09%09%09try%20%7B%0A%09%09%09%09%09//%20....%0A%09%09%09%09%7D%20finally%20%7B%0A%09%09%09%09%09nc5.dispose%28%29%3B%0A%09%09%09%09%7D%0A%09%09%09%7D%20catch%20%28ConstructionException%20e%29%20%7B%0A%09%09%09%09System.out.println%28e%29%3B%0A%09%09%09%7D%0A%0A%09%09%09finally%20%7B%0A%09%09%09%09nc4.dispose%28%29%3B%0A%09%09%09%7D%0A%09%09%7D%20catch%20%28ConstructionException%20e%29%20%7B%0A%09%09%09System.out.println%28e%29%3B%0A%09%09%7D%0A%09%7D%0A%7D%0A%60%60%60%0Asection1%20%u5C31%u662F%u4E00%u4E2A%u7B80%u5355%u7684try-finally%u539F%u5219.%20section2%u4E3A%u4E86%u6784%u9020%u548C%u6E05%u7406%2C%u53EF%u4EE5%u770B%u5230%u5177%u6709%u4E0D%u80FD%u5931%u8D25%u7684%u6784%u9020%u5668%u7684%u5BF9%u8C61%u7EC4%u5408%u5728%u4E00%u8D77%0Asection3%u5C55%u793A%u4E86%u5982%u4F55%u5904%u7406%u53EF%u4EE5%u5931%u8D25%u7684%u6784%u9020%u5668%u4E14%u9700%u8981%u6E05%u7406%u7684%u5BF9%u8C61.%20%28%u53EF%u7ED5%u6B7B%u6211%u4E86...%29%0A%0A%23%23%u5F02%u5E38%u7684%u5339%u914D%0A%u4E00%u53E5%u8BDD%2C%u5B9E%u5728%u61D2%u5F97%u5199%u4E86%2C%u5728%u629B%u51FA%u5F02%u5E38%u4E4B%u540E%2C%u5F02%u5E38%u5904%u7406%u7A0B%u5E8F%u4F1A%u6309%u7167%u4EE3%u7801%u7684%u4E66%u5199%u987A%u5E8F%2C%u627E%u51FA%22%u6700%u8FD1%22%u7684%u5339%u914D%u4E0A%u7684%u5904%u7406%u4EE3%u7801.%20%u8FD9%u91CC%u6240%u8C13%u7684%u5339%u914D%2C%u5305%u62EC%u5176%u57FA%u7C7B.%20%u6240%u4EE5%u5728%u4E66%u5199%u7684%u65F6%u5019%2C%u6700%u597D%u6309%u7167%22%u7531%u5C0F%u5230%u5927%22%u7684%u987A%u5E8F%u6765%u4E66%u5199.%20%0A%0A%23%23%u5176%u4ED6%u4E71%u4E03%u516B%u7CDF%0A%20%u5F02%u5E38%u5904%u7406%u7684%u4E00%u4E2A%u91CD%u8981%u539F%u5219%2C%u5728%u4F60%u77E5%u9053%u5982%u4F55%u5904%u7406%u7684%u60C5%u51B5%u4E0B%u624D%u6355%u83B7%u5B83.%20%u5B9E%u9645%u4E0A%u5F02%u5E38%u5904%u7406%u7684%u4E00%u4E2A%u91CD%u8981%u76EE%u6807%u5C31%u662F%u5C06%u9519%u8BEF%u5904%u7406%u7684%u4EE3%u7801%u548C%u53D1%u751F%u9519%u8BEF%u7684%u5730%u70B9%u76F8%u5206%u79BB.%20%0A%0A


原文地址:https://www.cnblogs.com/thecatcher/p/5922649.html