一、JAVA异常的体系结构
① Error:Java虚拟机无法解决的严重问题;一般不编写正对性的代码处理;
② Exception:其他因为编程错误或偶然的外在因素导致的一般性问题;可以进行异常处理;处理完后不影响程序的运行;
a.Exception又可以分为运行时异常和编译时异常;
①编译时异常(check):编译报错,要求必须处理,否则编译不通过;例如IOException、ClassNotFoundException
②运行时异常(unchecked RuntimExceprion):一般不处理;例如:NullPointerExcepion(空指针异常),ArrayIndexOutOfBoundsException(数组越界异常),ClassCastExcetption(类转换异常),NumberFormateException...
二、异常处理的两种方式:
①不直接处理,往调用层抛出异常 throw + 异常类型;
②处理异常:try{}catch(){}finally{}
一下为异常处理的throw的方式:抛出异常,单元测试会报相应的NumberFormatException异常,无法执行到抛出异常后的语句;
1 @Test2 public voidtestx() {3 String str = "abc";4 int num =Integer.parseInt(str);5 System.out.println("hello -1");6 throw newNumberFormatException();7 //System.out.println("hello -2");
8 }
一下为异常处理的try catch的方式:单元测试通过,并且执行了System.out.println("hello -2");
1 @Test2 public voidtest1() {3 String str = "abc";4 try{5
6 int num =Integer.parseInt(str);7 System.out.println("hello -1");8 }catch(NumberFormatException e) {//如果NumberFormatException换成时 NullPointerException则还是抛出异常
9 System.out.println("出现数值转换异常了。。。。");10 String mes =e.getMessage();11 System.out.println(mes);//常用异常处理方式1
12 e.printStackTrace();//常用异常处理方式2
13
14 }15 System.out.println("hello -2");16 }
三、过程:
过程一、“抛”;程序在正常执行过程中,一旦出现异常,就会在异常代码处生成一个对应异常的对象;并将此对象抛出;
一旦抛出异常,其后面的代码不再执行;
关于异常对象的产生,1,系统生成 的,2.手动生成一个异常对象并且抛出;throw;
过程二:“抓”:可以理解为异常处理方式:
try catch finally的使用:
try{
//可能出现异常的代码
}catch(异常类型1 变量名){
//处理异常方式1
}catch(异常类型2 变量名){
//处理异常方式2
}catch(异常类型3 变量名){
//处理异常方式3
}
........
finally{
//一定会执行的代码
}
说明:
1.finaly 是可选的
2。使用try将肯出现的代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,
根据此对象的类型,去catch中进行匹配
3.一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常处理,一旦处理完成就跳出try-catch结构(在没有finally的情况),
继续执行后面的代码;
4.catch中的异常类型如果没有子父类关系,则谁声明在上面,谁声明在下,无所谓,
catch中的异常类型如果满足子父类关系,则要求子类在上,父类在下,否则报错;
5.常用的异常处理方式 a.String getMessage() ;b printStackTrace();
6.在try中声明的变量,出了try结构就不能调用;
7.try catch finally 结构可以嵌套
例如:
@Testpublic voidtest2() {int a= 10;int b = 0;try{
System.out.println(a/b);
}catch(ArithmeticException e){
e.printStackTrace();
}finally{
System.out.println("finally~~~");//: handle finally clause
}
}
该程序 Junit通过,控制台打印异常和finally~~~;因为程序执行到 System.out.println(a /b);b=0所以 出现了错误,生成ArithmeticException对象,与catch中的异常进行匹配,匹配上后,进行异常处理,处理完成,执行finally中的代码;
1 @Test2 public voidtest3() {3
4 Day16ErrorAndExceptionDiscriable6 tt = newDay16ErrorAndExceptionDiscriable6();5
6 System.out.println(tt.finallyTest());7 }8
9 public intfinallyTest() {10 try{11 int[] arr = new int[10];12 //System.out.println(arr[10]); 打开或者关闭,return都是3; 3之前是inally~~~
13 return 0;14 } catch(ArrayIndexOutOfBoundsException e){15 e.printStackTrace();16 return 1;17 }finally{18 System.out.println("finally~~~");19 return 3;20 //: handle finally clause
21 }22 }
必须要处理的异常:如若需要调用时,必须要处理异常,或者是再往上抛出异常;
1 public void method() throwsFileNotFoundException,IOException{2 File file = new File("hello.txt");3 FileInputStream fis = null;4 fis = newFileInputStream(file);5 int data =fis.read();6 while(data != -1) {7 data =fis.read();8 }9 fis.close();10 }11
12 public void method2() throwsFileNotFoundException,IOException{13 method();14 }
1 @Test2 public voidtest4() {3 File file = new File("hello.txt");4 FileInputStream fis = null;5 try{6 fis = newFileInputStream(file);7 int data =fis.read();8 while(data != -1) {9 data =fis.read();10 }11 } catch(FileNotFoundException e) {12 e.printStackTrace();13 }catch(IOException e) {14 e.printStackTrace();15 }finally{16 try{17 if(fis != null) {18 fis.close();19 }20 } catch(IOException e) {21 //TODO Auto-generated catch block
22 e.printStackTrace();23 }24 }25
26
27 }
体会:
try catch finally真正把异常处理掉,
throws 的方式只是将异常抛给了方法的调用者,并没有真正的处理掉异常
开发中,如何选择try catch finally OR throws?
1.如果父类中被重写的方法没有throws,则子类重写的方法也不能throws,意味着如果子类重写的方法有异常,必须用try catch finally;
2.执行的方法A中,先后又调用了另外的几个方法,这几个方法是递进的关系执行的,建议这几个方法使用throws的翻翻,而执行的方法A可以考虑使用try catch finally;
四、如何自定义异常
1.继承于现有的异常体系RuntionExceptioin Exception
2.提供全局常量:serialVersionUID;表示类是否是同一个类
1 class MyException extendsRuntimeException{2 static final long serialVersionUID = 1111111111111111l;3 publicMyException() {4
5 }6 publicMyException(String message) {7 super(message);8 }9 }
1 classStudent{2 private intid;3 public void regist(intid) {4 if(id>0) {5 this.id =id;6 }else{7 //throw new RuntimeException("您输入的数据非法");//可以不处理,如果是Exceprion ,必须处理;
8 throw new MyException("您输入的数据非法");//抛出自定义异常
9 }10 }11 public void regist1(int id) throwsException {12 if(id>0) {13 this.id =id;14 }else{15 throw new Exception("您输入的数据非法");//可以不处理,如果是Exceprion ,则需要处理(两种方式),因为exception包括编译异常,所以必须要处理
16
17 }18 }19 }