1、异常的体系
/* ------|Throwable:所有异常和错误的超类 ----------|Error(错误):错误一般用于jvm或者硬件引发的问题,所以我们一般不会通过代码去处理错误的 ----------|Exception(异常):是需要通过代码去处理 --------------|运行时异常:如果一个方法内部抛出一个运行时异常,那么在方法上面可以声明也可以不声明,调用者可以处理或者不处理 --------------|编译时异常(非运行时异常,受检查异常):如果一个方法内部抛出了一个编译时异常,在方法上面必须要声明,而且调用者也必须处理. */
如何区分错误与异常:
1.如果程序出现了不正常的信息,如果不正常的信息以Exception结尾,那么肯定是一个异常.
2.如果是以Error结尾,那么肯定是一个错误.
运行时异常:RunTimeException以及RunTimeException的子类都是运行时异常.
编译时异常:除了运行时异常就是编译时异常.
疑问:为嘛java中编译器会如此严格要求编译时异常,对运行时异常如此宽松?
答:因为运行时异常都是可以通过程序员良好的习惯去避免,所有java编译器就没有那么严格要求处理运行时异常
2、异常的处理
2.1、方式一:捕获异常
捕获异常的格式:
try{
可能发生异常的代码
}catch(捕获异常的类型 变量名){
处理异常的代码
}
2.2、捕获异常要注意的细节
1.如果try块中的代码出现异常过后,那么try-catch块外面的代码可以正常执行.
2.如果try块中出现异常代码,那么try块中出现异常代码的后面的代码是不会执行.
3.一个try块后面可以跟多个catch块的,也就是一个try块可以捕获更多的类型的
4.一个try块中可以捕获多种异常的类型,但是捕获异常类型必须从小到大进行捕获,否则编译错误
疑问一:以后捕获异常处理的时候就是用Exception即可?
答:错误,因为我们现实开发中遇到不同的异常类型时候,我们往往有不同的解决方式。所以要分开不同的异常类型处理
疑问二:下面的信息是通过printStackTrace方法打印出来的,那么异常对象从何而来
Exception in thread "main" java.lang.ArithmeticException: / by zero at Demo2.div(Demo2.java:12) at Demo2.main(Demo2.java:8) |
答:jvm运行到a/b 这个语句时,发现b为0,除数为0在我们现实生活中属于不正常的情况,jvm一旦发现这种不正常时,那么jvm就马上创建异常对象,并且会调用这个异常对象的printStactTrace的方法来处理
1 //捕获异常 2 class Demo14 { 3 public static void main(String[] args){ 4 int[] arr=null; 5 div(4,0,arr); 6 } 7 public static void div(int a,int b,int[] arr){ 8 try{ 9 int c=a/b; //只要这一步出异常了,那么下面的输出语句就不执行了。所以运行的结果为:除数不能为0... 10 System.out.println("数组的长度:"+arr.length); 11 }catch(NullPointerException n){ 12 System.out.println("空指针异常..."); 13 }catch(ArithmeticException a1){ 14 System.out.println("除数不能为0..."); 15 }catch(Exception e){ 16 System.out.println("我是急诊室,包治百病!"); 17 } 18 } 19 }
结果图:
2.3、方式二:抛出异常
//抛出异常 class Demo13{ public static void main(String[] args){ try{ //捕获异常 div(4,0); System.out.println("Hello World!");//上面的语句出现异常,这条语句不执行 }catch(Exception e){ e.printStackTrace();//调用Exception中的printStackTrace()方法 打印异常信息 } } //在方法上声明抛出异常 public static void div(int a,int b) throws Exception{ //在同一行.... int c=a/b; throw new Exception(); } }
结果图:
2.4、抛出异常需要注意的细节
1.如果在一个方法内部抛出了一个异常对象,,那么必须要在方法上声明抛出
2.如果调用了一个声明抛出异常,那么调用者必须处理异常
3.如果一个方法内部抛出了一个异常对象,那么throw语句后面的代码就不会在执行了(一个方法遇到了throws关键字,那么该方法会马上停止执行)
4.在一种情况下,只能抛出一种异常对象.
疑问:何时采用抛出异常?何时使用到捕获异常呢?原则如何?
如果你需要通知调用者,你的代码有问题?那么这个时候使用抛出处理
如果你的代码直接与用户打交道,异常千万不能抛,在抛出的话,给了用户,这个时候就应该捕获异常了
3、throw 与throws关键字
1.throw关键字用于方法内部,throws用于方法的声明上
2.throw抛出的是一个对象,throws抛出的是一个异常类型
3.throw关键字只能抛出一个异常对象,throws可以抛出多个异常类型
4、自定义异常
自定异常类的步骤:自定义一个类继承Exception即可
1 //自定义异常 2 class NotIpException extends Exception{ 3 public NotIpException(String message){ 4 super(message); 5 } 6 } 7 //电脑版微信 8 class Demo15{ 9 public static void main(String[] args) { 10 //String ip="129.0.1.210"; 11 String ip=null; 12 try{ 13 weiXin(ip); 14 }catch(NotIpException e){ 15 e.printStackTrace();//打印异常信息 16 System.out.println("网线没有插好,或者您忘记缴费已断网!"); 17 } 18 } 19 public static void weiXin(String ip) throws NotIpException{ 20 if(ip==null){ 21 throw new NotIpException("网络异常"); 22 } 23 System.out.println("显示好友列表...."); 24 } 25 }
结果图:
5、finally关键字
5.1、finally 块
1、finally使用前提,必须存在try块才能使用.
2、finally块在任何情况下都会执行,除了退出jvm的情况
3、finally非常适合资源释放的工作,保证源文件在任何情况下都会被释放
5.2、try块的三种处理方式
方式一:
try{ 可能发生异常的代码 }ctach(捕获异常类型 变量名){ 处理异常的代码 }
方式二:
try{ 可能发生异常的代码 }ctach(捕获异常类型 变量名){ 处理异常的代码 }finally{ 释放资源的代码 }
方式三:
try{ 可能发生异常的代码 }finally{ 释放资源的代码 }
方式二的实例:
1 /* 2 finally释放资源 3 */ 4 import java.io.*; 5 class Demo2{ 6 public static void main(String[] args){ 7 FileReader fr=null; 8 try{ 9 //找到目标文件 10 File f=new File("F:\作业.txt"); 11 //创建文件与数据的通道s 12 fr=new FileReader(f); 13 //读取文件 14 char[] buf=new char[1024]; 15 int length=0; 16 length=fr.read(buf); 17 System.out.println("读取文件到内容"+new String(buf,0,length)); 18 }catch(IOException e){ 19 System.out.println("解析资源失败"); 20 }finally{//释放资源的finally块 21 try{ 22 fr.close(); 23 System.out.println("释放资源成功"); 24 }catch(IOException e){ 25 System.out.println("释放资源成失败"); 26 } 27 } 28 } 29 }
原创作者:DSHORE 作者主页:http://www.cnblogs.com/dshore123/ 原文出自:http://www.cnblogs.com/dshore123/p/8927993.html 欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!) |