java的异常处理

异常处理

一个catch块只能处理一类异常,当try块中的语句组可能抛出多种异常时,就需要有多个catch块来分别处理各种异常。

try{

int a=args.length;System.out.println("a=" + a);

int b=42/a; int c[]={1}; c[42]=99;

}catch(ArithmeticException e){

System.out.println("div by 0:" + e);

}catch(ArrayIndexOutOfBoundsException e){

System.out.println("array index oob:" + e);

}

一个异常对象能否被一个catch块接收主要看该异常对象与catch块中声明的异常类的匹配情况,当它们满足下面条件中的任一条时,异常对象将被接受:

异常对象是catch块中声明的异常类的实例;

异常对象是catch块中声明的异常类的子类的实例;

异常对象实现了catch块中声明的异常类的接口。

当使用多个catch块时,需注意catch子句排列顺序--先特殊到一般,也就是子类在父类前面。如果子类在父类后面,子类将永远不会到达。

8.5 catch语句块顺序的示例。

try语句的嵌套
一个try语句可以在另一个try块内部----try语句的嵌套。

每次进入try语句,异常的前后关系都会被压入堆栈。如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个try语句的catch处理程序将检查是否与之匹配。

这个过程将继续直到一个catch语句匹配成功,或者是直到所有的嵌套try语句被检查耗尽。

如果没有catch语句匹配,Java的运行时系统将处理这个异常。

8.6 运用嵌套try语句的示例。

分析:

1)当在没有命令行参数的情况下运行程序,外面的try块将产生一个被零除的异常。

2)程序在有一个命令行参数条件下运行,内部的try块将产生一个被零除的异常。因为与内部的catch块不匹配,它将把该异常传给外部的catch块来处理。

3)如果在具有两个命令行参数的条件下执行该程序,由内部try块产生一个数组下标越界异常,由内部的catch块处理。

finally语句块

某些情况下,不管异常是否发生,都需要处理某些语句,那么就将这些语句放到finally语句块中。finally语句所包含的代码在任何情况下都会被执行。

一个try语句至少有一个catch语句或finally语句与之匹配,但匹配的catch可以有多个,而finally语句只能有一个,并且finally语句并非必须有的。

8.7 finally的用法示例。main()方法中的语句为:

String[] friends={"Tom","葫芦娃","孙悟空"};

try{

for(inti=0;i<5;i++){

System.out.println(friends[i]);

}

}catch(ArrayIndexOutOfBoundsException e){

System.out.println("indexerr");

return;

}finally{

System.out.println("infinally block!");

}

System.out.println("this is theend");

抛出异常

Java运行时系统引发的异常

异常的抛出

根据需要人工创建并抛出

人工抛出异常

语法格式:throw 异常类对象;

例如:IOExceptione = new IOException();

throw e;

程序执行throw语句后立即终止,然后在包含它的所有try块中从里向外寻找含有与其类型匹配的catch子句。

8.7 throw语句的使用。

分析:

1main()调用方法demoproc()的过程中捕获并处理空指针异常。

2demoproc()方法也进行了相同的异常处理并且捕获该异常后将该异常抛出。

3)创建异常对象:throw newNullPointerException();
throw new NullPointerException(demo);

声明抛弃异常

如果一个方法中的代码在运行时可能生成某种异常,但是在本方法中不必要,或者不能确定如何处理此类异常时,则可以使用throws声明抛弃异常;

表明该方法中将不对此类异常进行处理,而由该方法的调用者负责处理;

即系统将在调用该方法的上层方法体内寻找合适的异常处理代码,而不再继续执行该方法的正常处理流程。

声明抛弃异常的格式
类型 方法名([参数表])throws 异常类型,…{
//
方法体;
}
8.8 声明抛弃异常。
static void procedure() {
System.out.println("insideprocedure");
throw newIllegalAccessException("demo");
}
public static void main(String args[]) {
procedure();
}

static void procedure() throwsIllegalAccessException{

System.out.println("inside procedure");

throw new IllegalAccessException("demo");

}

public static void main(String args[]){

try{

procedure();

}catch(IllegalAccessException e){

System.out.println("caught" + e);

}

}

自定义异常类

虽然Java的内置异常处理能够处理大多数常见错误,但用户仍需建立自己的异常类型来处理特殊情况。这时可以通过创建Exception的子类定义自己的异常类

格式:class 类名 extends Exception{

… …

}

8.10 自定义异常类。

分析:Exception类自己没有定义任何方法。但它继承了Throwable提供的一些方法。例如,

public String getMessage(); public void printStackTrace();

异常处理应注意的问题

对应用程序设计失误导致的数组越界、非法变量等类型的异常,如果要全部捕获所有类型的异常对象,会增加系统开销,导致程序的运行效率降低,建议应用程序可以不对此类异常进行捕获,而交由JVM进行处理。

对于实现输入/输出处理、网络通讯和数据库访问功能的代码,必须进行异常对象的捕获和处理。

断言

JDK1.4版本开始,Java语言引入了断言(assert机制。目的:程序调试

表现形式:断言就是程序中的一条语句,它对一个boolean表达式进行检查

一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态,系统给出警告或退出

如果没有断言机制Java程序通常使用if-elseswitch语句进行变量状态检查。缺点:

由于检查的数据类型不完全相同,这样的语句形式不会统一。

因为检查仅仅是应用在测试阶段,而if-elseswitch语句在发布以后仍然将起作用,如果消除这些代码就意味着要注释或者删除这些代码,如果这些代码量很大就意味着工作很繁重并存在风险。

使用断言的优点

Java程序员用统一的方式处理状态检查问题;

断言只需在发行的时候关闭该功能即可。

断言的开启和关闭

在默认情况下断言是关闭的,因此在使用断言以前,需要先开启断言功能,方法:
java –ea MyClass或者
java –enableassertions MyClass

关闭断言功能的方法:
java –da MyClass或者
java –disableassertions MyClass

注意:断言检查通常在开发和测试时开启。为了提高性能,在软件发布后,断言检查通常是例8-12 断言的使用。

public class TestAssertion1{

public static void main(String args[]){

int x=10;

System.out.println("Testing Assertion that x==100");

assert x==100:"Our assertion failed!";

System.out.println("Test passed!");

}

}

关闭的。

什么时候使用断言

通常来说,断言用于检查一些关键的值,并且这些值对整个程序,或者局部功能的完成有很大的影响。

断言表达式应该短小、易懂,如果需要评估复杂的表达式,应该使用函数计算。

使用断言的情况

检查控制流:在if-elseswitch语句中,可以在不应该发生的控制支流上加上assert语句。如果这种情况发生了,assert能够检查出来。

在私有方法计算前,检查输入参数是否有效
对于一些private的方法,要求输入满足一些特定的条件,可以在方法开头使用assert进行参数检查;对于公共方法,通常不使用断言检查

在方法计算后,检查方法结果是否有效

检查程序不变量
private boolean isBalance() {
……
}
//
assert isBalance():"balance is destoried";

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值