JAVA完全参考手册(第8版) 第10章 异常处理

1、try & catch

异常是运行时错误。可以由java运行时系统生成,也可以通过代码手动生成。五个关键字try catch throw throws finally

try{ }

catch(ExceptionType1 e1){ ... }

catch(ExceptionType2 e2){ System.out.println(e2); }

...

finally{ }

所有异常类型都是内置类Throwable的子类。两个分支,Exception类和Error类。Exception类有一个重要子类,RuntimeException;Error类定义了常规环境下不希望由程序捕获的异常,由java运行时系统使用以指示运行时本身出现了某些错误,堆栈溢出是一个例子。

处理异常有两个优点:允许修复错误和阻止程序自动终止。

一旦抛出异常,程序控制就会从try代码块转移出来,进入到catch代码块中,但是不会“返回”到try代码块中去。执行完catch继续进入整个try/catch代码块的下一行。catch子句的作用域被限定在由之前try语句指定的那些语句内。catch不能捕获由另一条try语句抛出的异常,但是嵌套的try语句是例外

不能为单条语句使用try。

多条catch语句。当抛出异常时,按顺序检查每条catch语句并执行类型和异常能够匹配的第一条catch子句,并忽略其他catch语句,并继续执行后面代码。异常子类必须位于所有超类之前,使用了某个超类的catch语句会捕获这个超类及其所有子类的异常。例如,ArithmeticException必须在Exception之前catch。

嵌套try语句。一条try语句可以位于另外一条try语句之中。每次遇到try语句异常的上下文就会被推入到堆栈中,如果内层的try语句没有为特定的异常提供catch,堆栈就会弹出该try语句检查下一条try语句的catch处理程序是否匹配,直到找到匹配的catch语句,或检查完所有的try语句。当涉及方法调用时,可能会出现不明显的try语句嵌套,可能在一个try代码块中包含了某个方法的调用,而在该方法内部又有另外一条try语句。

多重捕获。catch(ArithmeticException | ArrayIndexOutOfBoundsException e ) { ... }

2、throw

throw ThrowableInstance; //ThrowableInstance必须是Throwable或者其子类类型的对象。基本类型以及非Throwable类都不能用作异常。通过两种方式可以获得Throwable对象:catch子句中使用参数和使用new创建Throwable对象。

throw语句之后的执行流会立即停止,所有后续语句都不会执行。检查最近的try代码块,匹配catch,类推。例如,

class ThrowDemo {

static void demoproc() {

try {

thrownew NullPointerException("demo"); //构造了一个NullPointerException实例

} catch(NullPointerExceptione) {

System.out.println("Caught inside demoproc.")

throw e;

}

}

public static main(String args[]) {

try {

demoproc();  //不用创建对象

} catch(NullPointerExceptione) {

System.out.println(“Recaught: ” + e);

}

}

}

//输出为:Caught inside demoproc.

Recaught:java.lang.NullPointerException:demo

许多内置的java运行时异常至少有两个构造函数:一个不带参数,一个带有一个字符串参数。如果使用后者则参数指定了用来描述异常的字符串。

3、throws

在方法声明中提供throws语句。throws子句列出了方法可能抛出的所有异常类型,且必须声明。否则会编译时错误。

type method_name(parameter-list) throws exception-list{ ... } //exception-list由逗号隔开。

4、finally

异常可能使方法比预期时间更早地返回,此时finally可以解决诸如文件关闭(绕过异常机制)之类的问题。

不管是否抛出异常,都会执行finally代码块。不管是通过未捕获的异常还是使用显式的返回语句,都会在返回之前执行finally子句。

5、java的内置异常

java在java.lang中定义的未经过检查的RuntimeException子类(共17个)

参考链接:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html

http://blog.sina.com.cn/s/blog_4d8498800100dcm3.html

NullPointerException - 空指针引用异常

ClassCastException - 类型强制转换异常

    EnumConstantNotPresentException 试图使用未定义的枚举值

   IllegalArgumentException - 传递非法参数异常

   IllegalMonitorStateException - 非法的监视操作,例如等待未锁定的线程

   IllegalStateException - 环境或应用程序处于不正确的状态

   IllegalThreadStateException - 请求的操作与当前线程状态不兼容

   ArithmeticException - 算术运算异常

    ArrayIndexOutOfBoundsException 数组索引越界

   ArrayStoreException - 向数组中存放与声明类型不兼容对象异常

   IndexOutOfBoundsException - 下标越界异常

   NegativeArraySizeException - 创建一个大小为负数的数组错误异常

   NumberFormatException - 数字格式异常

   SecurityException - 安全异常

   StringIndexOutOfBounds 试图在字符串边界之外进行索引

   TypeNotPresentException - 类型未找到

   UnsupportedOperationException - 不支持的操作异常

java在java.lang中定义的经检查的异常

ClassNotFoundException  类未找到

CloneNotSupportedException  试图复制没有实现Cloneable接口的对象

IllegalAccessException  对类的访问被拒绝

InstantiationException  试图为抽象类或接口创建对象

InterruptedException  一个线程被另一个线程中断

NoSuchFieldException  请求的域变量不存在

NoSuchMethodException  请求的方法不存在

ReflectiveOperationException  与反射相关的异常子类

6、创建自己的异常子类

只需要定义Exception的子类即可。子类不需要实际实现任何内容——只要他们存在于类型系统中,既可以用作异常。

Exception类没有为自己定义任何方法,当然它继承了Throwable提供的方法(详见链接:http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html)。Exception类定义了四个构造函数,其中两个支持链式异常,另两个如下:Exception()  Exception(String msg)

例,

class MyException extends Exception {
	private int detail;
	
	MyException(int a) {
		detail = a;
	}
	
	public String toString() {
		return "MyException[" + detail + "]";
	}
}

class ExceptionDemo {
	static void compute(int a) throws MyException {
		System.out.println("Called compute(" + a + ")");
		if(a > 10) 
			throw new MyException(a);
		System.out.println("Normal exit");
	}
	
	public static void main(String args[]) {
		try {
			compute(1);
			compute(20);
		} catch(MyException e) {
			System.out.println("Caught " + e);
		}
	}
}

编译javac a.java,生成ExceptionDemo.class和MyException.class

运行java ExceptionDemo,结果如下:

Called compute(1)
Normal exit
Called compute(20)
Caught MyException[20]

7、链式异常

为异常关联另一个异常,第二个异常描述第一个异常的原因。链式异常可以包含所需要的任意深度。

为了使用链式异常,想Throwable类添加两个构造函数和方法:

Throwable(Throwable causeExc)   Throwable(String msg, Throwable causeExc)

//causeExc是引发当前异常的异常,msg允许同时指定该异常描述。

Throwable getCause()    Throwable initCause(Throwable causeExc)

//getCause()返回引发当前异常的异常,不存在则返回null,

//initCause()将causeExc和调用异常关联到一起并返回对异常的引用,每个异常对象只能调用一次initCause();如果通过构造函数设置了引发异常,那么就不能再使用initCause()进行设置。通常initCause()用于为不支持前面描述的两个附加构造函数的遗留异常类设置原因。


于2013/04/10

你可能感兴趣的:(Java学习)