自己学习,不喜勿喷~
1.异常的流程
try --> catch(可选) --> finally
2. 防止异常覆盖问题:
try {
throw new MyException("exception happen in try");
} catch (Exception e) {
throw new MyException("exception happen in catch");
} finally{
throw new MyException("exception happen in finally");
}
如果在某个程序段中出现类似的情况,控制台输出结果仅仅是 “exception happen in finally”,换句话说就是在 try 和catch代码段中出现的expection被覆盖了。如果我们回头找错误时,很难找到正确出现exception的位置。
解决的办法:将程序中所有可能出现Exception,存储到一个Vector中,在程序最后一次性将这个Vector抛出来 [用vector原因,个人觉得是vector大小可变]
3. 用throws子句抛出异常
将所有的异常都罗列在throws后,不要因为某些异常是前者的派生异常(可以理解为子类)而不写。
当覆写父类中含有throws的方法时需要注意:子类中该方法只能1.不抛出任何异常; 2. 抛出和父类相同的异常或者父类异常的子类异常, 不可以给子类覆写的方法添加新的throws的异常,如果在覆写的方法中出现了新的异常需要在方法内部直接处理掉,不可以抛出!
public class Base{
public void foo() throws FileNotFoundException{
throw new FileNotFoundException();
}
}
class TestBase extends Base{
public void foo() throws FileNotFoundException{
throw new FileNotFoundException();
}
}
4. 使用finally 避免资源泄露
在finally语句中关闭数据流等,防止数据被觊觎。
5. try/catch/finally使用规则:
a)当异常处理中存在finally块时,不要指望try代码块执行return、break或continue语句可以跳出函数,因为无论try中代码如何,finally语句永远都会执行
如果finally中包含有return,那么返回的将是finally中return的值
b)将循环体全部放入在try块中 [这样的执行速度要比try在循环体内要快,视JVM而定]:
public void foo() {
try {
for (int i = 0; i < array.length; i++) {
ai[i] = i;
}
} catch (Exception e) {
e.printStackTrace();
}
}
c)不要将异常用于流程控制! (没有正常的循环终止条件,使用异常终止循环,代码可以运行,但效率极其低下,果断重写!)
public void foo(){
try {
while(true){
if(condition){
throw new Exception();
}
}
} catch (Exception e) {
}
}
d)如果可以避免使用异常处理,尽量使用判断条件来屏蔽可能出现的异常
例如:如果处理空指针异常,可以先判断该对象是否为空,这样可以直接不需要用异常来处理,直接一句 if (Obj != null) 直观明了。
e)虽然java中的构造函数不是函数,但依然可以抛出异常,支持throws语句。这种方式是处理执行构造函数失败情况最好的方法(构造函数执行失败意味着new不出正确的对象)
class Foo{
BufferedReader br;
public Foo(String fileName) throws FileNotFoundException, IOException{
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String str = br.readLine();
this.br = br;
}
public void scanFile(){
try {
br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class MyTest{
public static void main(String[] args) {
Foo foo = null;
try {
foo = new Foo("a.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
foo.scanFile();
}
}
f)抛出异常之前将对象恢复为有效状态: 考虑下次执行这段代码时会发生什么事情,代码是否还能正常运行。