异常处理第八讲北京理工大学计算机系 金旭亮
2009-7-29 北京理工大学计算机系(共 28页) 2
关于异常
异常 ( Exception):发生于程序执行期间,表明出现了一个非法的运行状况。
例如:数组越界。
2009-7-29 北京理工大学计算机系(共 28页) 3
观看 Java异常示例
melon.java
异常处理的目的是提供不同的错误处理技术,
使程序更稳定,更安全;
异常处理的主要用途是提供准确的错误消息,
解释失败的原因、位置和错误类型等,同时提供一定的恢复能力,尽可能地降低出错的机率。
2009-7-29 北京理工大学计算机系(共 28页) 4
在程序中使用异常处理技术
没有任何异常处理代码:仅适用于编写不重要的程序,如讲课中的示例。
当异常发生时,结束应用程序。这是很不好的一种方法,因为程序占用的资源可能没有归还系统;
当导常发生时,捕获它,并根据情况进行处理,可能会结束程序,可能会提示重试操作,
可能会忽略异常并继续运行。
2009-7-29 北京理工大学计算机系(共 28页) 5
try 语句块
try {
可能发生运行错误的代码;
}
catch ( 异常类型 异常对象引用 ) {
用于处理异常的代码
}
finally
{
}
所有的异常都派生自 Exception类。
2009-7-29 北京理工大学计算机系(共 28页) 6
Java异常处理基础
当程序检测到出现了一个错误时会抛出一个异常对象。异常处理代码会捕获并处理这个错误。
把可能会发生错误的代码放进 try语句块中。
Catch语句块中的代码用于处理错误。
不管是否有异常发生,finally语句块中的语句始终保证被执行 。
关键字 throws用于生成一个可被系统捕获的异常对象修改 melon.java程序以实现异常捕获。
2009-7-29 北京理工大学计算机系(共 28页) 7
抛出异常
Throw语句可以抛出一个继承自 Throwable
类的对象
Throwable类有两个直接子类:
类 Exception:出现的问题是可以被捕获的;
类 Error:严重错误,无法被捕获。
当异常发生时,程序控制流程由 try语句块跳转到 catch语句块。
2009-7-29 北京理工大学计算机系(共 28页) 8
捕获一个异常
使用 catch语句,只能捕获 Exception类及其子类的对象
如果没有提供合适的出错处理代码,程序将会结束。
可以有多个 catch语句块,每个代码块捕获一种异常。
2009-7-29 北京理工大学计算机系(共 28页) 9
关于异常捕获(一)
认为在异常处理后控制将返回 throw后的第一条语句会导致错误;
指定由逗号分开的 catch参数表是语法错误,
catch只能有一个参数;
一个捕获 Exception对象的 catch语句块可以捕获所有异常;
在某个 try块后有两个不同的 catch 块捕获两个相同类型的异常是语法错误;
2009-7-29 北京理工大学计算机系(共 28页) 10
关于异常捕获(二)
将 catch(Exception e)放在别的 catch块前面会使这些 catch块都不执行,因此 Java不会编译这个程序
2009-7-29 北京理工大学计算机系(共 28页) 11
主动抛出异常
throw new ArithmeticException(… );
实例,ThrowDemo.java
2009-7-29 北京理工大学计算机系(共 28页) 12
多层嵌套异常
CatchWho.java
要注意哪个异常由哪个进行捕获
2009-7-29 北京理工大学计算机系(共 28页) 13
throws 语句
声明一个方法所能抛出的所有异常
int g(float h) throws a,b,c
{
// 方法体
}
如果一个方法调用了另一个有 throws异常声明的方法,除非在此方法中能捕获这些异常,
否则,必须在此方法中加上声明抛出这些异常的 throws语句。
2009-7-29 北京理工大学计算机系(共 28页) 14
Throws语句实例
ThrowsDemo.java
2009-7-29 北京理工大学计算机系(共 28页) 15
抛出异常的限制
一个子类的 throws表只能是其基类的 throws
表的子集
2009-7-29 北京理工大学计算机系(共 28页) 16
运行时异常
程序执行时发生的异常,派生于类
RuntimeException,例如:
ArrayIndexOutOfBoundsException
常见的两种运行时异常:
NullPointerException (没有创建对象实例却直接使用它)
ClassCastException(无效的类型转换)
2009-7-29 北京理工大学计算机系(共 28页) 17
受控与不受控的异常
Throws语句中声明的异常称为受控
( checked)的异常,
RuntimeException和 Error称为非受控的异常。
这种异常不用在 throws语句中声明。
2009-7-29 北京理工大学计算机系(共 28页) 18
可控异常与不可控异常类的实例
CheckedExceptionDemo.java
2009-7-29 北京理工大学计算机系(共 28页) 19
创建自己的异常类
Class OutofGas extends Exception
{ … }
Class banana
{
If ( fuel<0.1 ) throw new OutofGas();
}
2009-7-29 北京理工大学计算机系(共 28页) 20
使用多态创建自己的异常处理系统
catchException.java
( 1)派生自定义的异常类,根据实际情况抛出异常。
( 2)通过捕获基类异常对象来实现对所有子类异常对象的捕获。
捕获基类异常对象后,用 instanceof判断异常类型。
这是一种通用的异常处理策略。
2009-7-29 北京理工大学计算机系(共 28页) 21
关于多态异常捕获
将捕获超类对象的 catch块放在捕获该超类对象的子类对象的 catch之前是语法错误。
2009-7-29 北京理工大学计算机系(共 28页) 22
finally 语句块
资源泄露
当一个资源不再被程序使用,但程序本身并未向系统声明不再使用此资源时发生
Finally语句块主要用于解决资源泄露问题,
它位于 catch语句块之后,Java保证它们一定执行。
注意,Finally语句块中也可能发生异常,
如果这种情况发生,先前的异常被放弃。
2009-7-29 北京理工大学计算机系(共 28页) 23
异常处理实例
UsingExceptions.java:说明了
try/catch/finally机制的使用
运行结果:
Method throwException
Exception handled in method throwException
Finally executed in throwException
Exception handled in main
Method doesNotThrowException
Finally executed in doesNotThrowException
End of method doesNotThrowException !
2009-7-29 北京理工大学计算机系(共 28页) 24
异常的传播方式
采用堆栈的方式向上查找有关的错误处理程序。
2009-7-29 北京理工大学计算机系(共 28页) 25
了解异常发生的情况
使用 printStackTrace 和 getMessage
方法:
1,printStackTrace:打印方法调用堆栈。
2,每个 Throwable类的对象都有一个
getMessage方法,它返回一个字串,这个字串是在 Exception构造函数中传入的。
2009-7-29 北京理工大学计算机系(共 28页) 26
异常堆栈实例
PrintErrorStack,运行结果:
Exception thrown in method3
java.lang.Exception,Exception thrown in method3
at UsingExceptions.method3(UsingExceptions.java:36)
at UsingExceptions.method2(UsingExceptions.java:30)
at UsingExceptions.method1(UsingExceptions.java:24)
at UsingExceptions.main(UsingExceptions.java:11))
2009-7-29 北京理工大学计算机系(共 28页) 27
应用实例
EnhancedCarPayment.java
异常处理主要解决输入无效数字的情况
2009-7-29 北京理工大学计算机系(共 28页) 28
异常处理实例
DivideByZeroException.java
自定义异常 DivideByZeroException
捕获 NumberFormatException异常
指定方法可抛出的异常