java基础16 捕获、抛出以、自定义异常和 finally 块(以及关键字:throw 、throws)

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

欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!

 

posted @ 2018-04-24 12:19  DSHORE  阅读(270)  评论(0编辑  收藏