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_异常

    什么是异常? 异常是程序在“编译”或者“执行”的过程中可能出现的问题; 异常是应该尽量提前避免的; 异常可能也是无...

  • 11_异常类构建

    关键词: 异常类:计算异常、空指针异常、越界异常、内存不足异常、参数错误异常; 可复用代码库设计原则;数据结构依赖...

  • 个人成长集训营_19-李霞-深圳

    Day 11_项目管理

  • 聊聊MyBatis

    11_聊聊MyBatis - 文集 - 简书

  • 2022.11.13(阴)

    今天继续在家检测。王石11_

  • Android Chart框架 MPAndroidChart学习

    Android Chart框架 MPAndroidChart学习笔记11_图表的设置和样式 源码demo看这里 这...

  • 11_方法

    方法是与某些特定类型相关联的函数。类、结构体、枚举都可以定义实例方法和类型方法。与 Objective-C 不同,...

  • 11_组合模式

    又称为部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体...

  • 梓伊 的21天生命故事疗愈日记(第05天)

    ___2018___年_6_月_11_日 一、今天发生的哪些故事,让我觉得幸福和喜悦?我想感恩什么? 今天去了朋友...

  • 第05天(异常、文本文件处理)_03

    11_通过结构体生成json.go 12_通过map生成json.go 13_json解析到结构体.go 14_j...

网友评论

      本文标题:11_异常

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