疯狂java讲义总结-NO10

1. finally块用于回收在try块里打开的物理资源,异常机制会保证finally块总被执行。
2. Java将异常分为两种,Checked异常和Runtime异常,Java认为Checked异常都是可以在编译阶段被处理的异常,所以它强制程序处理所有的Checked异常;而Runtime异常则无须处理。
3. try块与if语句不一样,try块后的花括号({...})不可以省略,即使try块里只有一行代码,也不可省略这个花括号。与之类似的是,catch块后的花括号({...})也不可以省略。还有一点需要指出:try块里声明的变量是代码块内局部变量,它只在try块内有效,在catch块中不能访问该变量。
4. Java把所有的非正常情况分成两类:异常(Exception)和错误( Error),它们都继承Throwable父类。
5. Error错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程中断。
6. 实际上,进行异常捕获时不仅应该把Exception类对应的catch块放在最后,而且所有父类异常的catch块都应该排在子类异常catch块的后面(简称:先处理小异常,再处理大异常),否则将出现编译错误。
7. 在Java 7以前,每个catch块只能捕获一种类型的异常;但从Java 7开始,一个catch块可以捕获多种类型的异常。
8. 使用一个catch块捕获多种类型的异常时需要注意如下两个地方:
(1)捕获多种类型的异常时,多种异常类型之间用竖线(|)隔开。
(2)捕获多种类型的异常时,异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值。
9. 捕获多种类型的异常时,异常变量使用隐式的final修饰,如果对异常变量重新赋值将产生编译错误;捕获一种类型的异常时,异常变量没有final修饰,因此代码完全正确。
10.(1)getMessage()返回该异常的详细描述字符串。
(2)printStackTrace()将该异常的跟踪栈信息输出到标准错误输出。
(3)printStackTrace(PrintStream s)将该异常的跟踪栈信息输出到指定输出流。
(4)getStackTrace()返回该异常的跟踪栈信息。
11. Java的垃圾回收机制不会回收任何物理资源,垃圾回收机制只能回收堆内存中对象所占用的内存。
12. 有些时候,程序在try块里打开了一些物理资源(例如数据库连接、网络连接和磁盘文件等),这些物理资源都必须显式回收。
13. 异常处理语法结构中只有try块是必需的,也就是说,如果没有try块,则不能有后而的catch块和finally块;catch和finally块都是可选的,但catch块和finally块至少出现其中之一,也可以同时出现;可以有多个catch块,捕获父类异常的catch块必须位于捕获子类异常的后面;但不能只有try块,既没有catch块,也没有finally块;多个catch块必须位于try块之后,finally块必须位于所有的catch块之后。
14.如果在异常处理代码中使用System.exit(1)语句来退出虚拟机,则finally快将失去执行机会。
15. 尽量避免在finally块里使用return或throw等导致方法终止的语句,否则可能出现一些很奇怪的情况。
16. 异常处理流程代码可以放在任何能放可执行性代码的地方,因此完整的异常处理流程既可放在try块里,也可放在catch块里,还可放在finally块里。
17. 为了保证try语句可以正常关闭资源,这些资源实现类必须实现AutoCloseable或
Closeable接口,实现这两个接口就必须实现close()方法。
18. 自动关闭资源的try语句相当于包含了隐式的finally块(这个finally块用于关闭资源),因此这个try语句可以既没有catch块,也没有finally块。
19. 只有java语言提供了Checked异常,其他语言都没有提供Checked异常。Java认为Checked异常都是可以被处理(修复)的异常,所以Java程序必须显式处理Checked异常。如果程序没有处理Checked异常,该程序在编译时就会发生错误,无法通过编译。
20. 对于Checked异常的处理方式有如下两种:
(1)当前方法明确知道如何处理该异常,程序应该使用try...catch块来捕获该异常,然后在对应的catch块中修复该异常。
(2)当前方法不知道如何处理这种异常,应该在定义该方法时声明抛出该异常。
21. Runtime异常则更加灵活,Runtime异常无须显式声明抛出,如果程序需要捕获Runtime异常,也可以使用try...catch块来实现。
22. 使用throws声明抛出异常的思路是,当前方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理;如果main方法也不知道如何处理这种类型的异常,也可以使用throws声明抛出异常,该异常将交给JVM处理。JVM对异常的处理方法是,打印异常的跟踪栈信息,并中止程序运行,这就是前面程序在遇到异常后自动结束的原因。
23. 一旦使用throws语句声明抛出该异常,程序就无须使用try...catch块来捕获该异常了。
24.在大部分时候推荐使用Runtime异常,而不使用Checked异常。尤其当程序需要自行抛出异常时,使用Runtime异常将更加简洁。
25. 但Checked异常也有其优势--—Checked异常能在编译时提醒程序员代码可能存在的问题,提醒程序员必须注意处理该异常,或者声明该异常由该方法调用者来处理,从而可以避免程序员因为粗心而忘记处理该异常的错误。
26. 如果需要在程序中自行抛出异常,则应使用throw语句,throw语句可以单独使用,throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常实例。
27. 不管是系统自动抛出的异常,还是程序员手动抛出的异常,Java运行时环境对异常的处理没有任何差别。
28. 如果throw语句抛出的异常是Checked异常,则该throw语句要么处于try块里,显式捕获该异常,要么放在一个带throws声明抛出的方法中,即把该异常交给该方法的调用者处理;如果throw语句抛出的异常是Runtime异常,则该语句无须放在try块里,也无须放在带throws声明抛出的方法中;程序既可以显式使用try... catch来捕获并处理该异常,也可以完全不理会该异常,把该异常交给该方法调用者处理。
29. 用户自定义异常都应该继承Exception基类,如果希望自定义Runtime异常,则应该继承RuntimeException基类。定义异常类时通常需要提供两个构造器:一个是无参数的构造器;另一个是带一个字符串参数的构造器,这个字符串将作为该异常对象的描述信息(也就是异常对象的getMessage()方法的返回值。
30. (1)在出现异常的方法内捕获并处理异常,该方法的调用者将不能再次捕获该异常。
(2)该方法签名中声明抛出该异常,将该异常完全交给方法调用者处理。
31. 把底层的原始异常直接传给用户是一种不负责任的表现。通常的做法是:程序先捕获原始异常,然后抛出一个新的业务异常,新的业务异常中包含了对用户的提示信息,这种处理方式被称为异常转译。
32. 这种把原始异常信息隐藏起来,仅向上提供必要的异常提示信息的处理方式,可以保证底层异常不会扩散到表现层,可以避免向上暴露太多的实现细节,这完全符合面向对象的封装原则。
这种把捕获一个异常然后接着抛出另一个异常,并把原始异常信息保存下来是一种典型的链式处理 (23种设计模式之一:职责链模式),也被称为“异常链”。
33. 异常对象的printStackTrace()方法用于打印异常的跟踪栈信息,根据printStackTrace()方法的输出结果,开发者可以找到异常的源头,并跟踪到异常一路触发的过程。
34. 虽然printStackTrace()方法可以很方便地用于追踪异常的发生情况,可以用它来调试程序,但在最后发布的程序中,应该避免使用它;而应该对捕获的异常进行适当的处理,而不是简单地将异常的跟踪栈信息打印出来。
35.异常处理规则:
(1)使程序代码混乱最小化。
(2)捕获并保留诊断信息。
(3)通知合适的人员。
(4)采用合适的方式结束异常活动。
36.(1)不要过度使用异常。
(2)不要使用过于庞大的try块。
(3)避免使用catch All语句。(Throwable t)
(4)不要忽略捕获到的异常。

 

posted @ 2016-08-11 18:16  ﹍。GG╊棒°  阅读(117)  评论(0)    收藏  举报