第 10章
例外处理
– 例外处理入门
– 受检、执行时期例外
– throw,throws
– 例外的继承架构例外处理入门
想尝试捕捉例外,可以使用 "try","catch"、
"finally"三个关键词组合的语法来达到
try {
//陈述句
}
catch(例外型态 名称 ) {
//例外处理
}
finally {
//一定会处理的区块
}
例外处理入门
public class CheckArgsDemo {
public static void main(String[] args) {
try {
System.out.printf("执行 %s功能 %n",args[0]);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("没有指定自变量 ");
e.printStackTrace();
}
}
}
例外处理入门
例外处理最好只用于错误处理,而不应是用于程序业务逻辑的一部份,因为例外的产生要消耗资源例外处理入门
以下应用例外处理的方式就不适当
下面的方式才是正确的
while(true) {
try {
System.out.println(args[i]);
i++;
}
catch(ArrayIndexOutOfBoundsException e) {
//,...
}
}
for(int i = 0; i < args.length;
i++) {
System.out.println(args[i]);
}
受检例外、执行时期例外
在某些情况下例外的发生是可预期的
– 例如使用输入输出功能
错误是可预期发生的这类例外称之为「受检例外」( Checked Exception)
受检例外编译程序会要求您进行例外处理
– 在使用 java.io.BufferedReader的 readLine()方法取得使用者输入时,编译程序会要求您于程序代码中明确告知如何处理
java.io.IOException
受检例外、执行时期例外
如果您不在程序中处理的话,例如将
IOException的 "catch"区块拿掉
CheckedExceptionDemo.java:9,unreported exception
java.io.IOException; must be caught or declared to be
thrown
受检例外、执行时期例外
try {
BufferedReader buf = new BufferedReader(
new InputStreamReader(System.in));
System.out.print("请输入整數,");
int input = Integer.parseInt(buf.readLine());
System.out.println("input x 10 = " + (input*10));
}
catch(IOException e) { // Checked Exception
System.out.println("I/O错誤 ");
}
catch(NumberFormatException e) { // Runtime Exception
System.out.println("输入必须为整 數 ");
}
受检例外、执行时期例外
像 NumberFortmatException例外是「执行时期例外」( Runtime exception)
例外是发生在程序执行期间,并不一定可预期它的发生,编译程序不要求您一定要处理
对于执行时期例外若没有处理,则例外会一直往外丢,最后由 JVM来处理例外,
JVM所作的就是显示例外堆栈讯息
throw,throws
想要自行丢出例外,可以使用 "throw"关键词,并生成指定的例外对象
try {
double data = 100 / 0.0;
System.out.println("浮点数零除," + data);
if(String.valueOf(data).equals("Infinity"))
throw new ArithmeticException("除零例外 ");
}
catch(ArithmeticException e) {
System.out.println(e);
}
在巢状的 try...catch结构时,必须注意该例外是由何者引发并由何者捕捉
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArrayIndexOutOfBoundsException e) {
….
}
throw new ArithmeticException();
}
catch(ArithmeticException e) {
….
}
catch(ArrayIndexOutOfBoundsException e) {
….
}
throw,throws
在方法中会有例外的发生,而您并不想在方法中直接处理,而想要由呼叫方法的呼叫者来处理
– 使用,throws”关键词
– java.ioBufferedReader的 readLine()方法就声明会丢出 java.io.IOException
private void someMethod(int[] arr) throws
ArrayIndexOutOfBoundsException,
ArithmeticException {
//实作
}
例外的继承架构
Throwable
Error
LinkageError
ThreadDeath
VirtualMachineError
....
Exception
ClassNotFoundException
CloneNotSupportedException
IllegalAccessException
....
RuntimeException
ArithmeticException
ArrayStoreException
ClassCastException
....
继承自
Throwable
继承自
Throwable
严重的系统错误,
不用处理也无法处理
Checkedexceptio
n,编译程序要求您要处理
Uncheckedexcep
tion,编译程序不要求您要处理例外的继承架构
Throwable类别拥有几个取得相关例外讯息的方法。
– getLocalizedMessage()
取得例外对象的区域化讯息描述
– getMessage()
取得例外对象的讯息描述
– printStackTrace()
显示例外的堆栈讯息,这个方法在追踪例外发生的根源时相当的有用,简单的说若 A方法中呼叫了 B方法,而 B方法中呼叫了
C方法,C方法产生了例外,则在处理这个例外时呼叫
printStackTrace()可以得知整个方法呼叫的过程,由此得知例外是如何被层层丢出的。
例外的继承架构
了解例外处理的继承架构是必要的
如果父类别例外对象在子类别例外对象之前被捕捉,则,catch”子类别例外对象的区块将永远不会被执行
编译程序也会帮您检查这个错误例外的继承架构
try {
throw new ArithmeticException("例外测試 ");
}
catch(Exceptione) {
System.out.println(e.toString());
}
catch(ArithmeticException e) {
System.out.println(e.toString());
}
例外的继承架构
try {
throw new ArithmeticException("例外测試 ");
}
catch(ArithmeticException e) {
System.out.println(e.toString());
}
catch(Exception e) {
System.out.println(e.toString());
}