一、异常概念
Java的异常处理机制是执行期间状况处理方式,能够将处理错误状况的程序代码摆在一个易阅读的位置;
这要依赖于你已经知道所调用的方法可能产生异常,因此编写出处理次可能性的程序代码;
查看方法的生命是否有throws语句即可知道该方法是否会抛出异常;
public void test() throws InterruptedException{
Thread.sleep(1000);
}
异常是一种Exception类型的对象,Exception的对象可以是其子类的实例;
编译器不会注意RuntimeException类型的异常,因此其不需要声明或被包在try/catch的块中,然而还是可以这么做;
编译器关心检查异常,程序必须认识有异常可能的存在;
二、有风险方法调用方式
1 处理
若要处理异常状况,就调用包在try/catch块中,并将异常处理/恢复程序放在catch块中;
1.1 处理异常
方法可抓住其他方法所抛出的异常,异常总是丢回给调用方;
public void test(){
try{
// 危险动作
Thread.sleep(1000);
}catch(Exception e){
// 尝试恢复
// 若无法从异常中恢复,至少也要使用printStackTrace()列出有用的信息
e.printStackTrace();
}finally{
// 无论如何都要执行,即使try或catch有return指令,也会执行
}
}
也可以抛出的异常父类来catch异常,但捕获所有异常,会导致不清楚哪里出错;
try{
laundry.doLaundry();
}catch(ClothingException e){
// 恢复代码
}
1.2 处理多重异常
若有必要,方法可抛出多个异常;
但方法的声明必需要含有全部可能的检查异常;(若两个或以上的异常有共同的父类,可只声明该父类)
public class Laundry{
public void doLaundry() throws PantsException, LingerieException{
// 可能抛出两个异常的程序代码
}
}
也可以异常的父类声明会抛出的异常;
public void doLaundry() throws ClothingException{
// 声明成ClothingException可抛出任何该类的子类
}
1.3 多个catch块
编译器会检查是否处理所有可能的异常,将个别的catch块逐个放在try块下;
public class Foo{
public void go(){
Laundry laundry = new Laundry();
try{
laundry.doLaundry();
}catch(PantsException pex){
// 恢复代码
}catch(LingerieException lex){
// 恢复代码
}
}
}
为每个需要单独处理的异常编写不同的catch块;
注意:多个catch块要从小到大排,因为Java虚拟机智慧从上往下找到第一个符合范围的异常处理块;
try{
laundry.doLaundry();
}catch(TeeShirtException tex){
// 恢复代码
}catch(LingerieException lex){
// 恢复代码
}catch(ClothingException cex){
// 恢复代码
}
1.4 异常处理规则
catch与finally不能没有try
try与catch之间不能有程序
try一定要有catch或finally
只带有finally的try必须要声明异常
2 声明(duck掉)
若不打算处理异常,将异常duck掉,抛给调用该方法的方法,若main()方法也duck掉异常,Java虚拟机就挂掉了;
会抛出异常的方法必须声明它会抛出异常,如InterruptedException;
public void test() throws InterruptedException{
// 危险动作
Thread.sleep(1000);
}