• 22. 异常(Eception)


    1. 现实生活的病

    现实生活中万物在发展和变化会出现各种各样不正常的现象。

    1)例如:人的成长过程中会生病。

    |——病

      |——不可治愈(癌症晚期)

      |——可治愈

        |——小病自行解决(上火,牙痛)

        |——去医院(感冒,发烧)

     

    同时我们的java也可以诊断和处理这些异常

    注意:

      除了RunntimeException和它的子类以外,其他的都是编译时异常,我们可以在api文档中查找,并不需要死记硬背

     

    2. java异常体系图

      

    |——Throwable  (实现类描述java的错误和异常)

      |——Error (错误)一般不通过代码去处理。

      |——Exceprion (异常)

        |——RuntimeException (运行时异常)jvm不强制要求进行处理

        |——编译时异常 jvm强制要求进行处理

     

    1)苦恼1:为什么Error错误一般不需要代码去处理呢?

      因为有些错误程序员是很难避免的,例如内存溢出,jvm默认管理的内存为64G如果超出这个范围就会报错

    //定义一个1G内存的数组
            byte[] buf = new byte[2014*2014*2014];
            System.out.println(buf);

    报错:

     

     

    错误(Error):

      它指的是一个合理的应用程序不能截获的严重的问题。大多数都是反常的情况。错误是JVM的一个故障(虽然它可以是任何系统级的服务)。

    所以,错误是很难处理的,一般的开发人员是无法处理这些错误的。比如内存溢出.

     

    2)苦恼2:为什么编译时异常jvm强制要求处理,而运行时异常jvm不强制要求处理呢?

      因为运行时异常可以通过程序员良好的编程习惯而避免,程序员可以直接找到问题代码进行处理,防止这种情况发生

    例如:

      当我们执行除法运算的时候我们只需要在方法里面加一个if判断(被除数不能为0),就可以避免被除数为0的情况

      而不需要抛出处理或者try...catch

     

    注意:

      a.运行时异常编译器不会检查程序员是否处理该异常,所以我们应该尽量避免这种异常的出现

     

     

    3.自行处理(try...catch)

      1)单个异常处理

        例如:

    class Demo2
    {
        public static void main(String[] args)
        {
            div(4,0);
        }
    
        public static void div(int a , int b){
        
            try{
                
                System.out.println(a/b);//可能出现的异常
            
            }catch(ArithmeticException e){//异常匹配
            
                e.printStackTrace();
                System.out.println("除数不能为0");
            }
            System.out.println("运算除法");
        }
    }

     


        注意:

          a.如果不用处理异常,在程序运行到病态代码时,后面的代码不会执行。如果处理了,后面的代码会正常执行

          b.如果我们需要一次处理多个异常我们需要在后面多添加几个catch语句

     

      2)多个异常处理

        例如:

    class Demo2
    {
        public static void main(String[] args)
        {
            int[] arr = { 1, 2 };
            arr = null;
            div(4,0,arr);
        }
    
        public static void div(int a , int b, int[] arr){
        
            try{
                System.out.println(arr[1]);//会报空指针异常
                System.out.println(a/b); //运算异常
                
            
            }catch(ArithmeticException e){//异常匹配
            
                e.printStackTrace();
                System.out.println("除数不能为0");
            }catch(NullPointerException  e){
                e.printStackTrace();
                System.out.println("数组为空");
            }
            System.out.println("运算除法");
        }
    }

     



      注意:

        a.try中多个异常同时出现,只会处理第一条出现异常的语句,剩余的异常不再处理。

      苦恼:如果是这样,难道我要记住所有的预定义异常吗?

        其实我们可以用多态的方式来捕获异常,进行处理

      
      例如: 

    class Demo2
    {
        public static void main(String[] args)
        {
            div(4,0);
        }
    
        public static void div(int a , int b){
        
            try{
                System.out.println(a/b); //运算异常
                
            }catch(Exception e){//异常匹配
                e.printStackTrace();
                System.out.println("除数不能为0");
            
            }
        }
    }

     



     

      注意:

        因为Exception是所有异常的父类所以无论try语句块中出现何种错误,都会进行处理,这样导致的是,我们没办法对特定异常进行特定的处理。

        所以我们一般在catch(Exception e)前捕获一些我们知道可能要出现异常的代码,而把catch(Exception e)写在后面防止我们不知道的异常发生

     

    3.抛出异常(throw throws)

      1)语法

          throws 异常名     声明异常

          throw new 异常名    抛出异常

     

      2)代码:

    class Demo2
    {
        public static void main(String[] args)
        {
            try{
                div(4,0);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    
        public static void div(int a , int b) throws Exception{
        
            if(b == 0){
                throw new Exception("除数为0");
            }
        }
    }

     


       注意:

          a.如果调用抛出异常的方法时,调用者必须处理异常或者抛出代码.

       

      苦恼:main方法抛出异常谁去处理呢?

         

      因为程序运行时jvm会调用main方法,所以如果main方法抛出异常jvm会自动处理

      代码:

    public static void main(String[] args) throws Exception
    {
       div(4,0);
    }

     



      在实际的开发中预定义的异常并不能帮我们解决所有问题,这时我们就需要自定义异常了

     

    4.自定义异常

      实例代码:

     

    /*
    
        需求:模拟自己去吃木桶饭,如果没有带够10块,就抛出异常
        带够就吃木桶饭
    
        Exception的构造方法:
            
            1. Exception()     构造详细消息为 null 的新异常。
    
            2. Exception(String message) 构造带指定详细消息的新异常。
              
            3. Exception(String message, Throwable cause)  构造带指定详细消息和原因的新异常。
              
            4. Exception(Throwable cause)
                
                根据指定的原因和 (cause==null ? null : cause.toString()) 的详细消息构造新异常(它通常包含 cause 的类和详细消息)。
    
    */
    
    
    class MoneyException extends Exception{
    
        public MoneyException(String message){
    
            //调用Exception一个参数的构造方法
            super(message);
        }
    }
    
    
    class  Demo1{
        
        public static void main(String[] args) {
            int money = 5;
            try{
            
                eat(money);
            
            }catch(MoneyException e){
                
                e.printStackTrace();
                System.out.println("跟我洗一个月的碗吧!");
            }    
            
        }
    
        public static void eat(int money)throws  MoneyException{
            
            if(money<10){
    
                 throw new MoneyException("吃霸王餐");
            }
            System.out.println("吃香喷喷的饭吧!");
        }
    }

     

     



    5. finally语句

      3)定义:

          无论程序正常还是异常,都会执行finally,除非jvm停止(System.exit(0))

      2)运用:

          因为我们不能对一个文件同时进行修改和删除,当一个人在删除文件时代码报错,这个时候我们就要释放资源(finally一般用于释放资源)

      

      3)语法:

          a.try{ // 可能发生异常的代码 } catch( 异常类的类型 e ){ // 当发生指定异常的时候的处理代码 }catch...

            比较适合用于专门的处理异常的代码,不适合释放资源的代码

     

          b.try{  } catch(){} finally{ // 释放资源的代码 }

            比较适合用于既要处理异常又有资源释放的代码

     

          C.try{  }finally{ // 释放资源 }

            比较适合处理的都是运行时异常且有资源释放的代码。

     

     

     

  • 相关阅读:
    linux常用统计命令
    linux文件处理命令
    linux三剑客和管道使用
    bash编程语法
    第八章:用通配符进行过滤
    第七章:数据过滤
    第六章:过滤数据
    第五章:排序检索数据
    第四章:检索数据
    第二章:MYSQL简介
  • 原文地址:https://www.cnblogs.com/zjdbk/p/8892013.html
Copyright © 2020-2023  润新知