一、JAVA异常的体系结构
① Error:Java虚拟机无法解决的严重问题;一般不编写正对性的代码处理;
② Exception:其他因为编程错误或偶然的外在因素导致的一般性问题;可以进行异常处理;处理完后不影响程序的运行;
a.Exception又可以分为运行时异常和编译时异常;
①编译时异常(check):编译报错,要求必须处理,否则编译不通过;例如IOException、ClassNotFoundException
②运行时异常(unchecked RuntimExceprion):一般不处理;例如:NullPointerExcepion(空指针异常),ArrayIndexOutOfBoundsException(数组越界异常),ClassCastExcetption(类转换异常),NumberFormateException...
二、异常处理的两种方式:
①不直接处理,往调用层抛出异常 throw + 异常类型;
②处理异常:try{}catch(){}finally{}
一下为异常处理的throw的方式:抛出异常,单元测试会报相应的NumberFormatException异常,无法执行到抛出异常后的语句;
1 @Test 2 public void testx() { 3 String str = "abc"; 4 int num = Integer.parseInt(str); 5 System.out.println("hello -1"); 6 throw new NumberFormatException(); 7 //System.out.println("hello -2"); 8 }
一下为异常处理的try catch的方式:单元测试通过,并且执行了System.out.println("hello -2");
1 @Test 2 public void test1() { 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 结构可以嵌套
例如:
@Test public void test2() { 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 @Test 2 public void test3() { 3 4 Day16ErrorAndExceptionDiscriable6 tt = new Day16ErrorAndExceptionDiscriable6(); 5 6 System.out.println(tt.finallyTest()); 7 } 8 9 public int finallyTest() { 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() throws FileNotFoundException,IOException{ 2 File file = new File("hello.txt"); 3 FileInputStream fis = null; 4 fis = new FileInputStream(file); 5 int data = fis.read(); 6 while(data != -1) { 7 data = fis.read(); 8 } 9 fis.close(); 10 } 11 12 public void method2() throws FileNotFoundException,IOException{ 13 method(); 14 }
1 @Test 2 public void test4() { 3 File file = new File("hello.txt"); 4 FileInputStream fis = null; 5 try { 6 fis = new FileInputStream(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 extends RuntimeException{ 2 static final long serialVersionUID = 1111111111111111l; 3 public MyException() { 4 5 } 6 public MyException(String message) { 7 super(message); 8 } 9 }
1 class Student{ 2 private int id; 3 public void regist(int id) { 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) throws Exception { 12 if(id>0) { 13 this.id = id; 14 }else { 15 throw new Exception("您输入的数据非法");//可以不处理,如果是Exceprion ,则需要处理(两种方式),因为exception包括编译异常,所以必须要处理 16 17 } 18 } 19 }