11_异常

作者: 真是个点子王 | 来源:发表于2020-12-09 16:54 被阅读0次

    什么是异常?

    • 异常是程序在“编译”或者“执行”的过程中可能出现的问题;
    • 异常是应该尽量提前避免的;
    • 异常可能也是无法绝对避免的,异常可能有太多情况
    • 异常一旦出现,如果没有提前干预,程序就会退出JVM虚拟机

    异常的体系

    • Java中异常继承的根类是:Throwable
    • Error:错误,严重错误的Error,无法通过处理的错误,一旦出现,程序员无能为力
    • Exception:异常类,它是开发中代码在编译或者执行的过程中可能出现的错误,它是需要提前处理的。
      • 编译时异常:继承自Exception的异常或者子类,编译阶段就会报错
      • 运行时异常:继承自RuntimeException的异常或者子类,编译阶段不会出错,它是在运行时可能出现的,运行时异常可以处理也可以不处理,编译阶段是不会出错的,但是在运行阶段可能出现,还是建议提前处理。

    运行时异常的概念

    • 继承自RuntimeException的异常或者其子类;
    • 编译阶段是不会出错的,它是在运行时阶段可能出现的错误;
    • 运行时异常编译阶段可以处理也可以不处理,代码编译都能通过
    • 常见运行时异常列举:
      • 1.数组索引越界异常: ArrayIndexOutOfBoundsException。
      • 2.空指针异常 : NullPointerException。直接输出没有问题。但是调用空指针的变量的功能就会报错!!
      • 3.类型转换异常:ClassCastException。
      • 4.迭代器遍历没有此元素异常:NoSuchElementException。
      • 5.数学操作异常:ArithmeticException。
      • 6.数字转换异常: NumberFormatException。

    编译时异常

    • Java中,Exception类中除了RuntimeException类及其子类都是编译时异常。编译时异常的特点是Java编译器会对其进行检查,如果出现异常就必须对异常进行处理,否则程序无法通过编译。

    异常的默认处理机制

    public class ExceptionDemo {
        public static void main(String[] args) {
            System.out.println("程序开始。。。。。。。。。。");
            chu( 10 ,0 );
            System.out.println("程序结束。。。。。。。。。。");
        }
    
        public static void chu(int a , int b){
            System.out.println(a);
            System.out.println(b);
            int c = a / b ;// 出现了运行时异常,自动创建异常对象:ArithmeticException
            System.out.println("结果是:"+c);
        }
    }
    
    • 1.默认会在出现异常的代码那里自动的创建一个异常对象:ArithmeticException
    • 2.异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给JVM虚拟机;
    • 3.虚拟机接收到异常对象后,先在控制台直接输出异常栈信息数据;
    • 4.直接从当前执行的异常点干掉当前程序;
    • 5.后续代码没有执行机会,因为程序已经死亡。

    编译时异常处理机制


    方式一:直接异常抛出

    • 在出现编译时异常的地方层层把异常抛出去给调用者,调用者最终抛出给JVM虚拟机。JVM虚拟机输出异常信息,直接干掉程序,这种方式与默认方式是一样的。虽然可以解决代码编译时的错误,但是一旦运行时真的出现异常,程序还是会立即死亡,这种方式并不好。
    • 异常抛出的格式:
    方法 throws 异常1 ,  异常2 , ..{
            }
    建议抛出异常的方式:代表可以抛出一切异常,
    方法 throws Exception{
    
            }
    
    • 示例:
    public class ExceptionDemo01 {
    
        public static void main(String[] args) throws Exception {
            System.out.println("程序开始。。。。");
            parseDate("2013-03-23 10:19:23");
            System.out.println("程序结束。。。。。");
        }
    
        // Exception是异常最高类型可以抛出一切异常!
        public static void parseDate(String time) throws Exception{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date d = sdf.parse(time);
            System.out.println(d);
    
            InputStream is = new FileInputStream("D:/meinv.jpg");
        }
    }
    

    方式二:在异常出现的地方捕获处理

    • 在异常发生的地方,处理异常,并不会使程序直接死亡;
    • 这种方法存在的问题是上层调用者不能直接的知道底层的执行情况;
    • 语法:
      try{
      // 监视可能出现异常的代码!
      }catch(异常类型1 变量){
      // 处理异常
      }catch(异常类型2 变量){
      // 处理异常
      }...
    
    监视捕获处理异常企业级写法:
      try{
       // 可能出现异常的代码!
      }catch (Exception e){
          e.printStackTrace(); // 直接打印异常栈信息
      }
       //Exception可以捕获处理一切异常类型!
    
    • 实例代码:
    public class ExceptionDemo02 {
    
        public static void main(String[] args) {
            System.out.println("程序开始。。。。");
            parseDate("2013-03-23 10:19:23");
            System.out.println("程序结束。。。。。");
        }
    
        public static void parseDate(String time)  {
            try{
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date d = sdf.parse(time);
                System.out.println(d);
    
                InputStream is = new FileInputStream("D:/meinv.png");
            } catch (Exception e) {
                e.printStackTrace(); // 打印异常栈信息
            }
        }
    
        // JDK 1.7之后
    //    public static void parseDate(String time)  {
    //        try{
    //            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //            Date d = sdf.parse(time);
    //            System.out.println(d);
    //
    //            InputStream is = new FileInputStream("D:/meinv.png");
    //        } catch (FileNotFoundException|ParseException e) {
    //            e.printStackTrace(); // 打印异常栈信息
    //        }
    //    }
    
    //    public static void parseDate(String time)  {
    //        try{
    //            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
    //            Date d = sdf.parse(time);
    //            System.out.println(d);
    //
    //            InputStream is = new FileInputStream("D:/meinv.png");
    //        } catch (FileNotFoundException e) {
    //            e.printStackTrace(); // 打印异常栈信息
    //        } catch (ParseException e) {
    //            e.printStackTrace(); // 打印异常栈信息
    //        }
    //    }
    
    
        public static void parseDate1(String time)  {
            try{
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
                Date d = sdf.parse(time);
                System.out.println(d);
    
                InputStream is = new FileInputStream("D:/meinv.png");
            } catch (FileNotFoundException e) {
                System.err.println("文件根本不存在!");
            } catch (ParseException e) {
                System.err.println("解析有问题,请检查代码!");
            }
        }
    }
    

    方式三:在底层抛出异常,在上层统一捕获处理

    • 底层出现的异常抛出给最外层调用者集中捕获处理。这种方案最外层调用者可以知道底层执行的情况,同时程序在出现异常后也不会立即死亡。
    • 示例代码:
    public class ExceptionDemo03 {
    
        public static void main(String[] args) {
            System.out.println("程序开始。。。。");
            try {
                parseDate("2013-03-23 10:19:23");
                System.out.println("功能成功执行!!");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("功能执行失败!!");
            }
            System.out.println("程序结束。。。。。");
        }
        // 可以拦截所以异常!
        public static void parseDate(String time) throws Exception {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date d = sdf.parse(time);
            System.out.println(d);
    
            InputStream is = new FileInputStream("D:/meinv.png");
        }
    }
    

    运行时异常处理机制


    • 运行时异常在编译阶段是不会报错的,在运行阶段才会出错;
    • 一旦程序出错,如果没有处理异常,那么程序还是会死亡;
    • 运行时异常是自动往外抛出的,不需要我们手工抛出;
    • 直接在最外层捕获处理即可,底层会自动抛出。
    public class ExceptionDemo {
        public static void main(String[] args) {
            System.out.println("程序开始。。。。");
            try{
                chu(10 , 0);
                System.out.println("操作成功!");
            }catch (Exception e){
                e.printStackTrace();
                System.out.println("操作失败!");
            }
            System.out.println("程序结束。。。。");
        }
    
        public static void chu(int a , int b)  {
            System.out.println( a / b );
        }
    }
    

    finally关键字

    • 有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。例如,资源释放。
            try{
                // 可能出现异常的代码!
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                // 无论代码是出现异常还是正常执行,最终一定要执行这里的代码!!
            }try{
                // 可能出现异常的代码!
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                // 无论代码是出现异常还是正常执行,最终一定要执行这里的代码!!
            }
    

    finallyreturn注意事项

    • 情况一:finally代码块中的语句会先于return执行
       public static int chu1(){
            try{
                int a = 10 / 2 ;
                return a ;
            }catch (Exception e){
                e.printStackTrace();
                return -1;
            }finally {
                System.out.println("=====finally被执行");
            }
        }
    
    • 情况二:finally代码块中的return会覆盖其余位置的return
    public static int chu1(){
            try{
                int a = 10 / 2 ;
                return a ;
            }catch (Exception e){
                e.printStackTrace();
                return -1;
            }finally {
                System.out.println("=====finally被执行");
                return 111; // 不建议在finally中写return,会覆盖前面所有的return值!
            }
        }
    

    相关文章

      网友评论

          本文标题:11_异常

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