• 异常的分类、产生、传递和处理(JAVA基础十)


    一、异常

    1.1 概念

    异常:程序在运行过程中出现的特殊情况。

    1.2 异常的必要性

    任何程序都可能存在大量的未知问题、错误。

    如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失。

    二、异常分类


    Throwable:可抛出的,一切错误或异常的父类,位于java.lang包中。

    2.1 错误

    • Error: JVM、硬件、执行逻辑错误,不能手动处理。
    • 常见错误: StackOverflowError、 OutOfMemoryError等。
    • 你的游戏8G内存 : 2G
    • StackOverflowError : 如果是由于逻辑代码问题,需要改正,比如死循环

    2.2 异常

    • Exception:程序在运行和配置中产生的问题,可处理。
      • RuntimeException:运行时异常,可处理,可不处理。
      • CheckedException:检查时异常,必须处理。

    常见运行时异常:

    异常描述
    NullPointerException空指针异常
    ArrayIndexOutOfBoundsException数组越界异常
    ClassCastException类型转换异常
    NumberFormatException数字格式化异常
    ArithmeticException算术异常

    案例演示:

    package com.qfedu.test01;
    
    import java.util.Comparator;
    import java.util.Set;
    import java.util.TreeSet;
    
    //1.异常
        //1. Error  错误,不可修正  内存溢出, 堆溢出
        //2. 代码逻辑报错是:  Exception   程序运行期间
    
    //Exception   抛出异常
    // NullPointerException 空指针异常    没有初始化对象(Null) ==》 这种情况你去调方法和属性
    // ArrayIndexOutOfBoundsException 数组下标越界
    // ClassCastException  类转换异常
    //NumberFormatException  数据格式异常
    // ArithmeticException 算术异常
    public class Test01 {
        public static void main(String[] args) {
    
            String str = null;
            //int length = str.length();
    
            int[] a = new  int[9]; // index 0-8
            //a[9] = 10;
    
            Object o = "444";
            //Integer i  = (Integer)o;
    
            // TreeSet 实现排序, 里边的对象,实现Comparable    重写compareTo
            Set<Test01> s = new TreeSet<>();
           // s.add(new Test01());
    
            String str1 ="1+我";
            //Integer integer = Integer.valueOf(str1);
            //System.out.println(integer);
    
            System.out.println(1/0);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    三、异常产生和传递

    3.1 异常产生

    • 自动抛出异常:当程序在运行时遇到不符合规范的代码或结果时,会产生异常。
    • 手动抛出异常:语法:throw new 异常类型(“实际参数”)。
    • 产生异常结果:相当于遇到 return语句,导致程序因异常而终止。

    3.2 异常传递(这个其实是在打印信息中显示)

    • 异常的传递:
      • 按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)。
    • 受查异常:throws 声明异常,修饰在方法参数列表后端。
    • 运行时异常:因可处理可不处理,无需声明异常。

    案例演示:异常的产生、传递

    /**
     * 演示异常的产生和传递
     * 要求:输入两个数字实现两个数字相除
     */
    public class TestException1 {
    	public static void main(String[] args) {
    		operation();
    	}
    	public static void operation() {
    		System.out.println("---opration-----");
    		divide();
    	}
    	public static void divide() {
    		Scanner input=new Scanner(System.in);
    		System.out.println("请输入第一个数字");
    		int num1=input.nextInt();//出现异常,没有处理,程序中断
    		System.out.println("请输入第二个数字");
    		int num2=input.nextInt();
    		int result=num1/num2;//出现异常没有处理,所以程序中断
    		System.out.println("结果:"+result);
    		System.out.println("程序执行完毕了...");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    四、异常处理【重点】

    Java的异常处理是通过5个关键字来实现的:

    • try:执行可能产生异常的代码 。
    • catch:捕获异常 ,并处理。
    • finally:无论是否发生异常,代码总能执行。
    • throw: 手动抛出异常 。
    • throws:声明方法可能要抛出的各种异常。

    4.1 try…catch…

    语法:

    try {
    	//可能出现异常的代码
    } catch(Exception e) {
    	//异常处理的相关代码,如:getMessage()、printStackTrace()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注:1、正常请求 2、出现异常并处理 3、异常类型不匹配

    4.2 try…catch…finally…

    语法:

    
    ```java
    try {
    	//可能出现异常的代码
    } catch(Exception e) {
    	//异常处理的相关代码,如:getMessage()、printStackTrace()
    } finally{
    	//是否发生异常都会执行,可以释放资源等。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    package com.qfedu.exception;
    
    import com.qfedu.Hero;
    
    import java.lang.reflect.Method;
    
    public class Test3 {
    
        public static void main(String[] args) {
    
            add();
    
        }
    
        public  static void add() {
    
            try{
                Class<?> aClass = Class.forName("hahaero");
                Hero o = (Hero) aClass.newInstance();
    
                o.add(1);
    
            } catch (ClassNotFoundException e) {
                //打印异常
                System.out.println("我发生异常了,ClassNotFoundException,我退出了。。");
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } finally { //最终的意思
                //必要的操作是要完了,比如释放资源
                //连接数据库
                System.out.println("比如释放资源");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    注:1、finally块是否发生异常都执行,释放资源等 2、finally块不执行的唯一情况,退出java虚拟机

    4.3 多重catch

    语法:

    try{
    	//可能出现异常的代码。
    }catch(异常类型1){
    	//满足异常类型1执行的相关代码。
    }catch(异常类型2){
    	//满足异常类型2执行的相关代码。
    }catch(异常类型3){
    	//满足异常类型3执行的相关代码
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    public class TestException4 {
    	public static void main(String[] args) {
    		Scanner input=new Scanner(System.in);
    		int result=0;
    		try {
    //			String string=null;
    //			System.out.println(string.equals("hello"));
    			System.out.println("请输入第一个数字");
    			int num1=input.nextInt();//InputMismatchException
    			System.out.println("请输入第二个数字");
    			int num2=input.nextInt();
    			result=num1/num2;//发生异常// ArethmicException
    		}catch (ArithmeticException e) {//捕获 Exception:是所有异常的父类	
    			System.out.println("算术异常");
    		}catch (InputMismatchException e) {
    			System.out.println("输入不匹配异常");
    		}catch (Exception e) {
    			System.out.println("未知异常");
    		}
    		System.out.println("结果是:"+result);
    		System.out.println("程序结束了...");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    注意:

    4.4 try…finally…

    • try…finally…不能捕获异常 ,仅仅用来当发生异常时,用来释放资源。
    • 一般用在底层代码,只释放资源不做异常处理,把异常向上抛出。

    语法:

    try{
    	//可能出现异常的代码
    }finally{
    	//是否发生异常都会执行,可以释放资源等
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    package com.qfedu.exception;
    
    import com.qfedu.Hero;
    
    import java.lang.reflect.Method;
    
    public class Test4
    {
        public static void main(String[] args) {
    
             int a = add("com.qfedu.Hero");
    
            System.out.println(a);
        }
    
        public static   int add(String type) {
            try {
    
                if(type  != null) {
    
                    //进一步判断 type 是不com.qfedu
                    if(type.startsWith("com.qfedu")) {
    
                        //1.发生异常
                        Class<?> aClass = Class.forName(type);
    
                        Hero o = (Hero) aClass.newInstance();
                        o.add(1);
    
                        System.out.println("3333333");
                        return 1;
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } finally {
                System.out.println("哈哈");
            }
            return 0;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    4.5 小结

    • try{ } catch{ }
    • try{ } catch{ } catch{ }
    • try{ } catch{ } finally{ }
    • try{ } catch{ } catch{ } finally{ }
    • try{ } finally{ }

    注:多重catch,遵循从子( 小 )到父( 大 )的顺序,父类异常在最后

    五、声明、抛出异常

    5.1 声明异常 在方法上用 throws

    如果在一个方法体中抛出了异常,如何通知调用者?

    • throws关键字:声明异常
    package com.qfedu.exception;
    
    import com.qfedu.Hero;
    
    public class Test5 {
    
        public static void main(String[] args) {
            //try catch在上层方法里捕捉异常
            try {
                add("com.qfedu.Hero");
                System.out.println("aaaa");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
    
        public static void add(String type) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    
            //1.发生异常
            Class<?> aClass = Class.forName(type);
    
            Hero o = (Hero) aClass.newInstance();
            o.add(1);
    
            System.out.println("3333333");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    5.2 抛出异常(在代码中用 throw new )

    除了系统自动抛出异常外,有些问题需要程序员自行抛出异常。

    • throw关键字:抛出异常
    package com.qfedu.exception;
    
    import java.util.Scanner;
    
    public class Test6 {
    
        public static void main(String[] args) {
    
            Scanner scanner = new Scanner(System.in);
            int i = scanner.nextInt();
            int j = scanner.nextInt();
    
            if(j==0) {
                throw new RuntimeException("除数不能为0");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    六、自定义异常

    6.1 编写自定义异常

    • 需继承Exception或Exception的子类,代表特定问题。
    • 异常类型名称望文生义,可在发生特定问题时抛出对应的异常。

    常用构造方法:

    • 无参数构造方法。
    • String message参数的构造方法。
    package com.qfedu.exception;
    
    public class HeroException extends RuntimeException {
    
        public HeroException() {
        }
    
        //message 指的是错误信息
        public HeroException(String message) {
            super(message); //调用父类的有参构造器
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    package com.qfedu.exception;
    
    import java.util.Scanner;
    
    public class Test6 {
    
        public static void main(String[] args) {
    
            Scanner scanner = new Scanner(System.in);
            int i = scanner.nextInt();
            int j = scanner.nextInt();
    
            if(i==0) {
                 // throw new RuntimeException
                throw new HeroException("i 不建议是0,否则 除的没有意义 ");
            }
    
            if(j==0) {
                throw new RuntimeException("除数不能为0");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    6.2 异常中方法覆盖

    带有异常声明的方法重写:

    • 子类中的方法抛出的异常 <= 父类检查时异常。
    public class Animal {
    	public void eat() throw Excetion{
    		System.out.println("父类吃方法..........");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class Dog extends Animal{
    	@Override
    	public void eat() throw RuntimeException{ 
            //出现错误,父类没有声明异常,子类不能声明异常
    		System.out.println("子类的吃的方法..........");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    在fastapi中实现异步
    基于安卓Java试题库在线考试系统uniapp 微信小程序
    力扣 593. 有效的正方形
    解决adb root命令时错误 adbd cannot run as root in production builds
    MySQL问题:2002 - Can‘t connect to server on ‘localhost‘(10061)【已解决】
    对比学习15篇顶会论文及代码合集,2023最新
    tomcat启动配置java_home,启动网址等,点击startup.bat直接启动
    性能专题|实战角度分析JVM 源码
    铁路关基保护新规发布!铁路软件供应链安全洞察与治理思路
    如何下不可选中的文章
  • 原文地址:https://blog.csdn.net/LCHONSEONE/article/details/127699757