08 异常

作者: RobertLiu123 | 来源:发表于2019-02-28 08:32 被阅读0次

    我们通常称一个人不正常的时候说你有病啊,从大的范围来讲病主要有两种病,一种不可治疗,如艾滋、晚期癌症,另一种可治疗,这种可治疗的病又分成两类,一种如小感冒的不需要去医院处理,另一种如阑尾炎必须去医院处理,程序中也有这种不正常的情况,


    异常体系.png

    比如执行

    System.out.println(args[0]);
    

    会报异常
    ···

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
        at com.neusoft.test.Test.main(Test.java:8)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
    

    如果把args指向null,就会报如下异常

    Exception in thread "main" java.lang.NullPointerException
        at com.neusoft.test.Test.main(Test.java:9)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
    

    这些不正常的情况,统称为异常,JAVA是面向对象的语言,任何事物都可以用类来表述,我们就用各种类来表述异常,成为异常类,很多异常类堆积起来,就形成JAVA异常体系,任何异常类错误类都有一个父类叫Throwable,先来看一下Throwable常用方法
    toString()返回完整类名+病信息

     Throwable t = new Throwable();
            String s = t.toString();
            System.out.println(t);
    

    getMessage()返回创建Throwable对象传入的信息

     Throwable t = new Throwable();
            String s = t.getMessage();
            System.out.println(s);
    

    会发现,输出null,此时需要指定信息

    Throwable t = new Throwable("懒癌");
            String s = t.getMessage();
            System.out.println(s);
    

    printStackTrace()打印异常的栈信息
    举个例子,比方说看病


    image.png

    看肺炎,医生会一直问到底你的病的原因,肺炎的原因就是因为没盖被

    public static void test(){
            Throwable t = new Throwable();
            t.printStackTrace();
        }
    
     test();
    
    java.lang.Throwable
        at com.neusoft.test.Test.test(Test.java:14)
        at com.neusoft.test.Test.main(Test.java:11)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
    

    现在,让我们来看一看Throwable的子类
    error错误
    演示 字节码文件名不对就要解释,就会发生错误


    image.png

    Error是jvm或硬件出现的错误,一般不用编写代码去处理
    Exception是需要代码去进行处理
    如何区分错误与异常
    如果程序出现不正常的信息的类名是以Error结束,肯定是错误,如果是以Exception结束,肯定是异常
    异常

      public static void test(int a,int b){
            int c = a/b;
            System.out.println(c);
        }
    
    test(2,0);
    

    JAVA虚拟机运行到1/0的时候,马上创建一个异常对象,并调用异常对象的printStackTrace()方法
    那,出了问题总得要解决,现在就来学习异常处理的方式
    捕获处理
    try{
    }catch(Exception e){
    e.printStackTrace();
    }

    int c = 0;
    
            try {
                c = a/b;
                System.out.println("哈哈哈");
                int[] arr = null;
                System.out.println(arr.length);
            }catch(ArthmeticException e){
                System.out.println(e.toString());
            }catch(NullPointerException e){
                System.out.println(e.toString());
            }
            System.out.println(c);
    
    int c = 0;
    
            try {
                c = a/b;
                System.out.println("哈哈哈");
                int[] arr = null;
                System.out.println(arr.length);
            }catch(Exception e){
                System.out.println(e.toString());
            }catch(ArthmeticException e){
                System.out.println(e.toString());
            }catch(NullPointerException e){
                System.out.println(e.toString());
            }
            System.out.println(c);
    

    捕获异常要注意的细节
    1、try块中的异常经过处理,try块后的代码可以正常执行
    2、如果try块中出现了异常的代码,那么try块中异常代码之后的代码就不会执行
    3、一个try块后面是可以跟多个catch块,也就是一个try块可以捕获多种类型异常
    4、一个try块可以捕获多种类型的异常,但是异常的类型必须从小到大进行捕获,否则编译报错
    疑问1:捕捕获异常打印感觉没多大用
    异常处理非常有用,只不过我们目前接触到的非常有限度,举例:项目中跳到错误页面,就用到异常处理
    疑问2:以后捕获异常就弄一个Exception就够
    开发中会遇到不同的异常类型,因此就需要不同的异常处理方式
    抛出处理
    抛出处理要注意的细节
    1、如果一个方法内部抛出了异常,那么必须要在方法上声明抛出,就像住酒店可能会着火,所以提示,就像温馨提示
    2、如果调用一个声明抛出异常的方法,那调用者必须处理
    3、如果一个方法内部抛出一个异常对象,那么throw语句后面的代码都不会执行,该方法马上停止
    4、在一种情况下,一次只能抛出一种异常对象

    public static void test(int a,int b) throws Exception{
           if(b == 0){
               throw new Exception();
           }
           int c = a/b;
            System.out.println(c);
    
        }
    
    public static void test(int a,int b,int[] arr) throws Exception{
          if(b == 0||arr == null){
              throw new Exception();
              throw new NullPoiterException();
          }
          int c = a/b;
           System.out.println(c);
    
       }
    

    throw和throws
    1、throw关键字是用于方法内部,throws关键字是用于方法声明
    2、throw关键字是用于方法内部抛出一个异常对象,throws关键字是用于方法声明抛出异常类型
    3、throw关键字后只能跟一个异常对象,throws关键字一次可以跟多个异常类型
    疑问:抛出处理在何时使用
    如果你要通知到调用者,可以抛
    如果代码直接跟用户打交道,千万不要再抛,抛的话就给了用户,应该使用捕获异常
    自定义异常类
    sun给我们提供了很多异常类,用于表述异常,但还不足以表述所有异常,因此需要自定义,比如去购物,没带钱,那就是没带钱异常
    需求,模拟fq上线,如果没有插上网线,抛出没有插上网线异常,如果插上网线,就显示好友列表
    自定义异常类步骤
    自定义一个类继承Exception
    需求,模拟你去吃饭,只带10元,不够的情况下的异常
    运行时异常与编译时异常
    如果方法上声明了一个运行时异常,那么在方法上可以声明也可以不声明,调用者可以处理也可以不处理,如果一个方法内部抛出了一个编译时异常对象,那么方法上就必须要声明,调用者也必须处理
    RunTimeException及其子类都是运行时异常
    除了运行时异常就是编译时异常
    异常的类型不用记
    疑问:为什么jvm会如此严格要求编译时异常,对运行时异常如此宽松
    运行时异常都是好的编程习惯能避免,因此就没有严格要求运行时异常
    编译时异常是编写代码没法避免,比如读写文件,就有IOException,读硬盘数据硬盘坏掉,没法用代码规避
    finally块
    资源文件使用完一定要解除占用,别的程序无法对该文件进行操作
    使用finally的前提一定要使用try块

     public static void test(int a,int b) throws Exception{
           try {
               if (b == 0) {
                   return;
               }
           }catch(Exception e){
               e.printStackTrace();
           }finally {
               System.out.println("执行fianally块");
           }
    
    
        }
    

    return、throw等停止的方法都不会阻止finanlly,只有当调用System.exit()方法时才能停掉
    finally块非常适合用来释放资源,用finally块也肯定能释放资源
    try块的3种组合方式
    try{
    }catch(){
    }
    try{
    }catch(){
    }finally{
    }
    try{
    }finally{
    }
    其中,最后一种适合运行时异常

    相关文章

      网友评论

          本文标题:08 异常

          本文链接:https://www.haomeiwen.com/subject/gemcuqtx.html