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 - 向数组中存放与声明类型不兼容对象异常
IndexOutOfBoundsExceptio
NegativeArraySizeExcepti
NumberFormatException - 数字格式异常
SecurityException - 安全异常
StringIndexOutOfBounds 试图在字符串边界之外进行索引
TypeNotPresentException
UnsupportedOperationExce
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