• java异常处理机制


    异常处理机制

       异常并非语法错误,若语法错误,编译不通过,不会产生字节码文件,不能运行。异常处理衡量一门语言是否成熟的标准之一。异常处理机制可以让程序有更好的容错性,代码更健壮

    C语言没有异常处理机制,所以经常使用特定返回值来表示异常情况,然后使用if语句来判断正常和非正常关系, if-else就是异常处理的一种


     没有异常处理机制存在的缺点:
     1. 使用方法的返回值来表示异常的情况有限,无法穷举所有的异常情况。
     2. 异常流程和正常代码混合在一起,增大了程序的复杂性,可读性不好。
     3. 随着系统规模的扩大,程序的可维护性极低(耦合度太高)。

     Java异常体系
     
     1. 把不同类型的异常情况描述成不同的异常类
     2. 分离异常流程代码和正确流程代码
     3. 灵活处理  如何当前方法处理不了,交给调用者处理
     
     非正常情况:
     1. error:表示错误,一般指JVM相关的不可修复的代码,如系统崩溃,内存溢出,JVM错误,由JVM抛出,不需要处理

    几乎所有的子类都以Error作为类的后缀


     2. Exception:表示异常,指程序出现不正常的情况,该问题可以修复(处理异常),几乎所有的子类都是以Exception作为类型的后缀, XXXException
     
     抛出异常
     1.使用throw在方法内部,抛出一个异常对象
     2.使用throws在方法的声明上,抛出一个异常对象


       throw当一个方法出现未知异常的时候,抛出一个具体的异常类型,和return一样会结束当前方法

    1. 用在方法体内,跟的是异常对象名

    2.只能抛出一个异常对象名

    3.表示抛出异常,由方法体内的语句处理

    4.执行throw则一定抛出了某种异常 

      throws用来声明一个方法可能产生的所有异常当前方法不处理异常,而是将异常往上传,谁调用我我就抛给谁。如果每一个方法都放弃异常处理都直接通过throws声明抛出,最后异常会抛到main方法,如果main方法也不处理,就会继续抛出给JVM,底层的处理机制就是打印异常的跟踪栈信息

    1.用在方法声明后面,跟的是异常类名,可以跟多个异常类名,用逗号隔开。

    2.throws表示出现异常的一种可能性,并不一定会发生这些异常

    3.表示抛出异常,由该方法的调用者来处理

       //在本例中,异常由方法体内的语句处理

       public
    static void main(String[] args) { int num1,num2; num1 = 10; num2 = 0; System.out.println(divide(num1,num2)); } private static int divide(int num1,int num2) { System.out.println("begin........"); if(num2 == 0) { throw new ArithmeticException("除数不能为0"); } try { int ret = num1/num2; System.out.println("结果" + ret); } catch (ArithmeticException e) { e.printStackTrace(); } System.out.println("end..........."); return 0; }
       //除数为0,得到这样的结果:
       /*
           begin........
           Exception in thread "main" java.lang.ArithmeticException: 除数不能为0
           at com.tedu.day08.ThrowDemo.divide(ThrowDemo.java:55)
           at com.tedu.day08.ThrowDemo.main(ThrowDemo.java:47)
         */ }

    捕获和处理异常
     try catch
     try catch finally
     try finally

    以上的异常处理语法结构中
    注意:

    1. 只有try块是必须的,也就是说如果没有try块,则不可能有后面的catch块和finally块;
    2. catch块和finally块都是可选的,但catch块和finally块至少出现其中之一,也可以同时出现;
    3. 可以有多个catch块,捕获父类异常的catch块必须位于捕获子类异常的后面
    4. 不能只有try块,既没有catch块,也没有finally块;
    5. 多个catch块必须位于try块之后,finally块必须位于所有catch块之后。

    public static void main(String[] args) {
            //使用try-catch捕获异常
            /*
             * 使用try—catch捕获单个异常  (或多个异常)
             * try{
             *     编写可能会出现异常的代码
             * }catch(异常类型 e){
             *     处理异常的代码1
             *     //记录日志  打印异常信息 继续抛出异常
             * }catch(异常类型){
             *     异常处理2
             * }
             * 
             * 1.一个catch语句,只能捕获一种类型的异常,如果捕获多个,就必须使用多个catch语句
             * 2.代码在一瞬间只能出现一种类型的异常,只需要一个catch捕获,不可能同时出现多个异常
             * try{
             * 
             * }
             * catch(Exception e){//必须放到最后
             * }
             * 
             * try—catch必须连用
             * -------------------------------------------
             * 如何获取异常信息,使用Throwable类的方法
             * 1.getMessage()  获取异常的描述信息,原因提示给用户的时候  就提示错误原因
             * 
             * 2.toString()  获取异常的类型和异常描述信息
             * 
             * 3.printStackTrace()  打印异常的跟踪栈信息  并且输出都控制台,包含异常的类型,异常的原因还包括了异常出现的位置,在开发和调试阶段都
             * 得使用printStackTrace()
             * 
             * 注意:
             * 现在catch语句中,必须写e.printStackTrace()
             * 查看异常位置 信息
             */
            try {
                int ret = 10/0;
                System.out.println("结果" + ret);
            }catch(Exception e) {
                System.out.println("异常消息:" + e.getMessage());
                System.out.println("异常消息: " + e.toString());
                //打印信息到控制台
                e.printStackTrace();
            }
            System.out.println("---Throwable类,如何捕获异常信息");
        }
    }

    再看看finally的用法

    finally

    /*
     * finally  表示一个代码块
     * 特点:无论是否有异常,最终都会执行finally代码块  (有特殊情况,JVM退出)
     * 目的:释放资源
     * ---------------------------------------------
     * 比如当我们的try语句中开了一个物理资源(数据库,网络)
     * 都得在使用完之后,最终关闭打开的资源
     * ----------------------------------------------
     * finally
     * 1.try - finally  
     * 会有catch捕获异常,根据场景,抛出异常,不需要自己处理
     * 
     * 2.try - catch - finally 
     * 自身需要处理异常  最终还需要关闭资源
     * 注意:finally不能单独使用
     * ----------------------------------------------
     * 当只有在try 或者 catch 中调用退出JVM的方法  才不会执行finally (System.exit(0));
     * 否则finally一定会执行
     * ----------------------------------------------------------------------------
     * 
     * final修饰符,定义常量
     * finally代码块(特点如上)
     * finalize方法,垃圾回收机制
     * 
     * 
     */
    
    public class FinallyDemo {
        public static void main(String[] args) {
            
    //      text1();
            
            System.out.println(text2());
            
    //      System.out.println(text3());
    //        
    //      System.out.println(text4());
            
        }
        
        private static int text4() {//返回1
            int a = 1;
            try {
                return a;
            } finally {
                return a++;
            }
        }
        
        
        private static int text3() {//返回2
            int a = 1;
            try {
                return a;
            } finally {
                return ++a;
            }
        }
        //如果finally语句里面带有return语句
        //永远返回的是finally里面的值
        //需要避免该情况
        private static int text2() {
            try {
                System.out.println("aa");
                return 1;
            } finally {
                System.out.println("bb");
                return 100;//finally返回值会把try里面的返回值覆盖  这里返回100
            }
        }
    
        private static void text1() {
            System.out.println("begin.....");
            try {
                int ret = 0/0;
                System.out.println("结果" + ret);
            } 
            catch (Exception e) {
                System.out.println("异常");
            } 
            finally {
                System.out.println("关闭资源");
            }
            System.out.println("end......");
            
        }
    }
    /*
    使用finally回收资源

    有时候,程序在try块里面打开了一些物力资源(比如数据库连接,网络连接好磁盘文件等),这些物理资源都必须显式回收。因为java的垃圾回收机制不会回收任何的物理资源
    垃圾回收机制只回收堆内存中对象所占用的内存。


    问题:那么在哪边回收这些物理资源呢?

    答:在finally块中,因为如果try块的某条语句引起一场,该语句后的其他语句通常不会被执行,那将导致位于该语句后的资源回收语句得不到执行;如果在catch块里进行资源回收
    但catch块完全有可能得不到执行,这也将导致不能及时回收这些物理资源。所以我们不管try块中的代码是否出现异常,也不管哪个catch块会被执行,finally块总会被执行。

    那么:java异常处理的完整语法结构如下:

    try
    {
         //业务实现逻辑
         ...
    }
    catch(SubException e)
    {
         //异常处理块1
         ...
    }
    catch(SubException2 e)
    {
         //异常处理块2
         ...
    }
         ...
    finally
    {
        //资源回收块
        ...
    }

    参考:

    https://blog.csdn.net/weixin_38011265/article/details/79149313

    坚持学习,永远年轻,永远热泪盈眶
  • 相关阅读:
    C++STL——vector
    大数常用计算模板及例题
    在线算法&离线算法
    线段树——hdu1166敌兵布阵
    C++STL——堆栈
    C++STL——优先队列
    C++STL——队列
    图的建立——图的两种存储结构
    Manacher算法——最长回文子串
    HttpClient的几个实现类
  • 原文地址:https://www.cnblogs.com/jiang0123/p/11295122.html
Copyright © 2020-2023  润新知