zoukankan      html  css  js  c++  java
  • java 异常处理

    1.1 传统处理异常的方式

    public class Test01 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第一个数:");
            
            int num1 = 0;
            if(sc.hasNextInt()) {            
                num1 = sc.nextInt();
                
                System.out.println("请输入第二个数:");
                int num2 = 0;
                if(sc.hasNextInt()) {
                    num2 = sc.nextInt();
                    
                    if(0 == num2) {
                        System.out.println("除数不能为0!");
                    }else {                    
                        int r = num1 / num2;
                        System.out.println("num1/num2 = "+r);
                    }
    
                }else {
                    System.out.println("第二个数输入不是数字");
                }
                
            }else {
                System.out.println("第一个数输入不是数字!");
            }
        }
    }

    缺点:

    [1] 通过判断影响执行效率

    [2] 判断逻辑和业务逻辑交织在一起可维护性很差。

    1.1 异常

    异常是指在程序的运行过程中所发生的不正常的情况,它会中断正在运行的程序

    异常处理机制

    java中通过异常处理机制程序提供异常处理的能力,保持程序继续运行而不中断!

    1.3 异常处理

    涉及异常处理的关键字有try…catch/try…catch…finally

    1.3.1 try/catch

    可能产生异常的代码放到try代码块中,catch代码块负责捕获处理异常。

    [1]正常执行,出现任何异常

     

    [2]出现异常,异常处理,正常结束

    Exception是所有异常类的直接或者间接父类。

    异常常见方法

    printStackTrace:打印异常的执行堆栈信息

    java.util.InputMismatchException
        at java.util.Scanner.throwFor(Scanner.java:864)
        at java.util.Scanner.next(Scanner.java:1485)
        at java.util.Scanner.nextInt(Scanner.java:2117)
        at java.util.Scanner.nextInt(Scanner.java:2076)
        at cn.sxt02.exception02.Test01.main(Test01.java:14)

    一般而言,异常堆栈信息很多,开发者只需要看懂

    第一行:异常简单信息(异常类型异常的描述等)

    最后一行:异常出现的位置(->方法->方法具体的行)

    控制台中异常堆栈信息输出位置不固定

     

    getMessage:返回异常的描述信息

    package cn.sxt02.exception02;
    import java.util.Scanner;
    public class Test01 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第一个数:");
    
            int num1 = 0;
            int num2 = 0;
            try {
                num1 = sc.nextInt();
    
                System.out.println("请输入第二个数:");
                num2 = sc.nextInt();
    
                int r = num1 / num2;
                System.out.println("num1/num2 = " + r);
            }catch (Exception e) {
                System.out.println("程序出现异常");
                // 打印异常的信息
                // System.out.println(e.toString());
                
                
                // 打印异常堆栈信息
                 e.printStackTrace();
                
                // 返回异常的描述信息,如果没有信息,返回null(InputMismatchException 没有描述信息)
                System.out.println(e.getMessage());
            }
            
            System.out.println("程序正常结束");
        }
    }

    [3]异常类型不匹配

    [4] 多重catch

    public class Test03 {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第一个数:");
    
            int num1 = 0;
            int num2 = 0;
            
            try {
                num1 = sc.nextInt();
    
                System.out.println("请输入第二个数:");
                num2 = sc.nextInt();
    
                int r = num1 / num2;
                System.out.println("num1/num2 = " + r);
            }catch (ArithmeticException e) {
                System.out.println("数学计算异常:"+e.getMessage());
            }catch(InputMismatchException e) {
                System.out.println("输入不匹配异常:"+e.getMessage());
            }catch (Exception e) {
                System.out.println("发送异常:"+e.getMessage());
            }
            
            System.out.println("程序正常结束");
        }
    }

    1.3.2 try/catch/finally

    有可能产生异常的代码放到try中,catch负责匹配并处理异常,finally用于进行收尾工作(关闭数据库、关闭文件、释放内存等资源)

    不管是否发生异常,finally都执行。

    public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第一个数:");
    
            int num1 = 0;
            int num2 = 0;
    
            try {
                num1 = sc.nextInt();
    System.out.println("请输入第二个数:");
                num2 = sc.nextInt();
    
                int r = num1 / num2;
                System.out.println("num1/num2 = " + r);
            } catch (Exception e) {
                System.out.println("程序出现异常");
            } finally {
                System.out.println("不管是否出现异常,finally都执行");
            }
    
            System.out.println("程序正常结束");
        }

    finally 总是执行,常用进行收尾类工作。

    特殊情况

    [1] finally执行的情况。

    System.exit(0) 正常推出jvmfinally不会执行。

    [2]catch可以省略,变成try…finally

    1.3.3 return

    存在returntry/catch/finally执行顺序

    package cn.sxt02.exception03;
    
    /**
     * 存在return的情况
     */
    public class Test02 {
    
        public static int div(int a, int b) {
    
            try {
                int r = a / b;
                return r;
    
            } catch (Exception e) {
                System.out.println("出现异常");
    
                return 0;
    
            } finally {
                System.out.println("我是finally");
            }
    
        }
    
        public static void main(String[] args) {
    
            int r = Test02.div(10, 0);
            System.out.println("r=" + r);
            System.out.println("程序正常结束");
        }
    }

    1.1 异常的分类

     

    Throwable 类是 Java 语言中所有错误(Error)或异常(Exception)的父类只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。

     

    Error 表示错误类。仅靠程序本身无法恢复的严重错误。jvm内存耗尽、jvm崩溃等

    Exception 表示异常类可以通过java 异常处理机制处理。

     

    Exception 根据是否处理分为两种情况。

    RuntimeException:运行时异常。不要求程序必须做出处理。是所有运行时异常的父类。

    CheckedException:检查时异常。要求程序必须处理不处理编译不通过。

    常见的运行时异常

    ArithmeticException:数学计算异常。比如除数为0

    InputMismatchException:输入不匹配异常

    ArrayIndexOutofBoundsException:数组下标越界异常。

    NullPointException:空指针异常,对象没有初始化就使用时,jvm抛出该异常

    IllegalArgumentException:非法参数异常。

    ClassCastException:强制类型转换异常。

    NumberFormatException:数字格式化异常。比如把“abc”格式化成数字。

     

    常见的检查时异常:

    ClassNotFoundException:类没有被发现异常。

    SQLException:数据库相关异常

    IOException:IO操作异常

    ParseException:解析错误异常

    FileNotFoundException:文件未发现异常。

     

    运行时异常和检查时异常的区别

    运行时异常:包括RuntimeException及其所有子类。不要求程序必须对它们作出处理,比如InputMismatchException、ArithmeticException、NullPointerException等。即使没有使用try-catch或throws进行处理,仍旧可以进行编译和运行。如果运行时发生异常,会输出异常的堆栈信息并中止程序执行。

    Checked异常(非运行时异常):除了运行时异常外的其他异常类都是Checked异常。程序必须捕获或者声明抛出这种异常,否则出现编译错误,无法通过编译。处理方式包括两种:通过try-catch捕获异常,通过throws声明抛出异常从而交给上一级调用方法处理

     

    1.4 声明异常

    1.4.1 throws关键字

    一个方法可能存在异常,而此时自身又无法更好的处理,可以交给外界处理此时throws声明并抛出异常。

     

    public class Test01 {
    
        public static int div(int a, int b) throws ArithmeticException{
            int r = 0;
            r = a / b;
            return r;
        }
    
        public static void main(String[] args) {
            try {
                Test01.div(10, 0);
            } catch (ArithmeticException e) {
                System.out.println("除数不能为0");
            }
        }
    }

    开发者可以根据需要声明检查时异常(Exception或者非运行时异常)和运行时异常(RuntimeException其子类)

     

    如果调用处也不知道如何处理异常,可选择继续声明异常,我们把这个过程称为异常上抛

    public class Test01 {
    
        public static int div(int a, int b) throws Exception{
            int r = 0;
            r = a / b;
            return r;
        }
    
        public static void main(String[] args) throws Exception{
            
            //【1】 调用处知道如何处理!
            /*
            try {
                Test01.div(10, 0);
            } catch (Exception e) {
                e.printStackTrace();
            }
            */
            
            // 【2】调用处也不知道如何处理
            Test01.div(10, 0);
            
        }
    }

    1.4.2声明异常和重载的关系

    声明异常重载没有任何关系

    public class Test01 {
    
        public static int div(int a, int b) throws Exception{
            int r = 0;
            r = a / b;
            return r;
        }
        
        public static int div(int a, int b) {
            int r = 0;
            r = a / b;
            return r;
        }
    }

    方法

    [1]方法名相同
    [2]参数列表不同(个数、类型、顺序)

    [3]返回值、修饰符、声明异常无关。

    1.4.3 声明异常和重写的关系

    声明一个和方法重写有关系。

     [1]父类方法声明了异常(检测时或运行时),子类可以不声明任何异常。

    public class Father {
    
        public void showInfo() throws Exception{
            
        }
    }
    
    public class Son extends Father{
        
        @Override
        public void showInfo(){
            
        }
        
    }

    可以认为:父类方法抛出异常,子类在重写过程把该异常处理掉了所以子类方法不用声明异常

     [2] 父类方法声明没有声明任何异常(检测时或运行时),子类不声明异常或者声明运行时异常。

    public class Father {
    
        public void showInfo(){
            
        }
    }
    public class Son extends Father{
        
        @Override
        public void showInfo() throws Exception{
            
        }
        
    }

    [3] 父类声明了异常(检测时或运行时),子类声明完全一样的异常。

    public class Father {
    
        public void showInfo() throws Exception{
            
        }
    }
    public class Son extends Father{
        
        @Override
        public void showInfo() throws Exception {
            
        }
        
    }

     

     

  • 相关阅读:
    mysql主从复制配置
    mysql三种修改密码的方式
    mysqldump数据库备份与恢复
    mysql多实例安装
    线性回归与梯度下降法——原理与实现
    K-Means聚类算法原理
    EFcodeFirst+T4=操纵任意数据库
    涨姿势UWP源码——IsolatedStorage
    记一次Project插件开发
    基于Nodejs生态圈的TypeScript+React开发入门教程
  • 原文地址:https://www.cnblogs.com/FSY15767366954/p/10776496.html
Copyright © 2011-2022 走看看