10 java异常处理
Java异常
常见的异常
常见的异常例子
/** * * @author leak * 异常经常会发生,如果代码不控制好范围,约束 * 常见的异常 */ //注意下面的异常不能同时显示,要一个一个显示,如果想看哪个异常,就把前面出异常的地方注释掉,因为出现异常,下面的代码就不会执行。 public class Test { int c;//这里的变量测试空指针 public static void main(String[] args) { //ArrayIndexOutOfBoundsException数组越界异常 //数组越界异常,这里的String数组长度是3,也就是0,1,2,下面的循环是<4会输出0,1,2,3 //第4个数值超出了数值的长度,会报异常 String [] arrs ={"12","23","23"}; for(int i = 0 ; i < 4 ; i++) { System.out.println(arrs[i]); } //空指针异常NullPointerException Test a = new Test(); a = null ; //这里把a的指向null System.out.println(a.c);//因为a指向null,就是没有指向任何对象地址,所以a.c是不存在任何东西 //数学运算异常ArithmeticException //除数不能为0,任何数除以0没意义 System.out.println(5/0); } }
Java异常类层次
Throwable是顶级的异常父类,通常分为两大类异常,Error和Exception.
Error一般是比较严重的错误,Error是指正常情况下,不大可能出现的情况,绝大部分的Error都会导致程序处于非正常的、不可恢复的状态。既然是非正常情况,不便于也不需要捕获。常见的比如OutOfMemoryError之类都是Error的子类。
Exception又分为可检查(checked)异常和不可检查(unchecked)异常。可检查异常在源代码里必须显式的进行捕获处理,这是编译期检查的一部分。不可检查时异常是指运行时异常,像NullPointerException、ArrayIndexOutOfBoundsException之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。
异常处理
Exception异常有两种处理方法,一种是抓try{}catch(){},一种是抛throw.
异常捕捉
例子
/** * * @author leak * 异常处理机制 */ public class Test2 { public static void main(String[] args) { String [] arrs ={"12","23","23"}; //下面进行异常的捕捉 //捕捉异常 try { //用try{}来括一段有可能出现异常的代码段 System.out.println("1"); System.out.println(5/0);//由于异常,程序终止,可以通过异常处理机制防止程序中断 //注意:上面会出现数学运算异常,下面的数组越界异常不会执行,因为一旦捕捉到异常,直接进入catch体内 //还有异常不会同时捕捉多个,越在前面定义的异常,优先级高 //因为try里面的某一条语句产生异常,直接进入catch体内,一旦进入catch体,try里面产生异常的语句的 下面的语句不会执行了 //下面会数组越界异常 for(int i = 0 ; i < 4 ; i++) { System.out.println(arrs[i]); } System.out.println("2");//这里语句2不会执行,上面的代码出现异常,被捕捉,进入到catch里面 }catch(ArrayIndexOutOfBoundsException e) {//捕捉多个异常,可以使用连续的catch(){},不过小异常放在前面,范围大的异常放后面 e.printStackTrace();//这里不会执行,因为是数学运算异常,所以会被下面的catch捕捉 }catch(Exception e) {//Exception是所有异常的父类 e.printStackTrace();//捕捉异常之后,打印异常信息 }finally {//这个finally可以写/不写,它是捕捉异常体系中最终一段会执行的部分,未来学习io操作和JDBC操作都会接触 System.out.println("2最后一定会执行的finally语句"); } System.out.println("3ok");//由于上面捕捉了异常,所以程序正常运行,这句语句会被执行 } }
关于捕捉异常小总结:
try
捕获异常的第一步是用try{…}语句块选定捕获异常的范围,将可能出现异常的代码放在try语句块中。
catch (Exceptiontype e)
在catch语句块中是对异常对象进行处理的代码。每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。
如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。
可以用ArithmeticException类作为参数,也可以用RuntimeException类作为参数,或者用所有异常的父类Exception类作为参数。但不能是与ArithmeticException类无关的异常,如NullPointerException,那么,catch中的语句将不会执行。
捕捉到异常后可用:
getMessage( ) 方法,用来得到有关异常事件的信息
printStackTrace( )用来跟踪异常事件发生时执行堆栈的内容。
关于finally
捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try、catch代码块中是否发生了异常事件,finally块中的语句都会被执行。 ( finally语句是可选的)
异常抛出
例子
//测试类 public class Test3 { //main方法如果继续抛异常,就把异常抛给JVM虚拟机了,就在程序中不能处理 public static void main(String[] args) throws Exception { // B b = new B(); // try { // b.test();//调用方法,把方法抛出的异常处理,可以捕捉异常 // } catch (Exception e) { // e.printStackTrace(); // } // b.test();//也可以把异常继续抛出去,但是一般不要把异常抛给jvm,直接捕获 D d = new D(); try {//捕捉 调用方法的异常 d.test(-100); }catch(Exception e) { e.printStackTrace(); } } } //手动抛出异常类 class D{ int age; public void test(int age) throws Exception { if(age>0 && age<150) { System.out.println("正常年龄"); } else { //如果不满足条件,可以自己手动创建异常,抛出 throw new Exception("年龄不在0到150之间"); } } }
自定义异常类
例子
public class Test3 { //main方法如果继续抛异常,就把异常抛给JVM虚拟机了,就在程序中不能处理 public static void main(String[] args) throws Exception { D d = new D(); try {//捕捉 调用方法的异常 d.test(-100); }catch(Exception e) { e.printStackTrace(); } } } //自定义的异常类,自定义异常类必须继承异常类 class MyException extends Exception{ public MyException(String mess) { super(mess); } } class D{ int age; public void test(int age) throws Exception { if(age>0 && age<150) { System.out.println("正常年龄"); } else { //如果不满足条件,可以自己手动创建异常,抛出自定义异常 throw new MyException("年龄不在0到150之间"); } } }
Java提供的异常类一般是够用的,只有特殊的情况可能需要自己编写异常类,这种情况很少见。