30. 异常

news2024/11/29 0:38:40

异常

    • 1. 概述
    • 2. Throwable 方法
      • 2.1 概述
      • 2.2 代码示例
    • 3. 异常分类
    • 4. 异常处理方式
      • 4.1 JVM默认处理异常
      • 4.2 自己处理(捕获异常)`try...catch`
        • 4.2.1 概述
        • 4.2.2 灵魂四问
      • 4.3 抛出处理(throw和throws)
    • 5. 自定义异常
      • 5.1 概述
      • 5.2 代码示例
    • 6. 异常注意事项

文章中的部分照片来源于哔站黑马程序员阿伟老师处,仅用学习,无商用,侵权联系删除!

具体异常信息请查看 API 帮助文档

1. 概述

在Java中,错误(Error)类和异常(Exception)类都是继承自Throwable类,用于表示程序中出现的问题或异常情况。
在这里插入图片描述

  • 错误类(Error):错误类表示严重的问题,通常是由虚拟机内部错误或系统资源耗尽等问题引起的。这些错误类通常是无法恢复的,程序无法处理,也没有必要进行捕获和处理。

    • 需要注意的是,错误类通常由虚拟机自动抛出,而不需要代码中显式地进行捕获和处理。
  • 异常类(Exception):异常类用于表示程序中的正常但意外的情况。与错误类不同,异常类分为两类:编译异常运行异常

    • 编译异常(Checked Exception):编译异常指在编译阶段就需要处理的异常,编译器会强制要求程序员在代码中显式地捕获和处理这些异常。

      • 处理编译异常的方式可以是使用try-catch块捕获和处理异常,或者在方法中使用throws关键字声明可能抛出的受检异常。
    • 运行异常(Unchecked Exception):运行异常是在程序执行过程中发生的异常,不需要在代码中显式地捕获和处理。它们通常由代码中的错误或逻辑问题引起,如空指针异常(NullPointerException)或数组索引越界异常(ArrayIndexOutOfBoundsException)等。

      • 运行异常通常表示程序的逻辑错误或程序员的错误。
      • 处理运行异常的方式是可选择性地进行捕获和处理,也可以让程序崩溃并终止运行。
    • 需要注意的是,RuntimeException及其子类是Java中常见的运行异常类。

除了预定义的错误类和异常类,Java还允许使用者自定义异常类。通过继承Exception类其子类来创建自定义异常类,以更好地描述和处理特定的异常情况。

2. Throwable 方法

2.1 概述

  • Throwable 是 Java 中所有错误和异常的根类。它定义了处理错误和异常的基本方法和属性。

  • 需要注意的是,Throwable 是一个抽象类,不能直接实例化。

  • 它有两个直接子类:Error 和 Exception。

    • Error 类表示严重的错误,通常无法恢复;

    • Exception 类表示可处理的异常情况。

    • 开发者也可以继承 Throwable 类创建自定义的错误或异常类。

  • Throwable的成员方法:

    方法名称说明
    public string getMessage()返回此 throwable 的详细消息字符串
    public string toString()返回此可抛出的简短描述
    public void printStackTrace()用红色字体把异常的错误信息输出在控制台(仅仅是打印信息,不会停止虚拟机)
  • 正确的输出语句:System.out.println();

  • 错误的输出语句:(不是代码错误,而是用来打印错误信息的)System.err.println();

     细节:当正确的输出语句和错误的输出语句同时使用时,两者的输出顺序不确定。
    

2.2 代码示例

  • 代码示例
    package text.text02;
    
    /*
    Throwable的成员方法:
    
    | 方法名称                      | 说明                                                         |
    | ----------------------------- | ------------------------------------------------------------ |
    | public string getMessage()    | 返回此 throwable 的详细消息字符串                            |
    | public string tostring()      | 返回此可抛出的简短描述                                       |
    | public void printstackTrace() | 用红色字体把异常的错误信息输出在控制台(仅仅是打印信息,不会停止虚拟机) |
    
    正确的输出语句:System.out.println();
    错误的输出语句:(不是代码错误,而是用来打印错误信息的)System.err.println();
        细节:当正确的输出语句和错误的输出语句同时使用时,两者的输出顺序不确定。
     */
    public class text88 {
        public static void main(String[] args) {
            int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
    
            //1.public string getMessage(): 返回此 throwable 的详细消息字符串
            System.out.println("=============== 1.public string getMessage(): 返回此 throwable 的详细消息字符串 ===============");
    
            //自己处理(捕获异常)
            try {
                System.out.println(arr[10]);//索引越界异常 ArrayIndexOutOfBoundsException
            } catch (ArrayIndexOutOfBoundsException e) {
                String message = e.getMessage();
                System.out.println(message);
            }
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
    
    
            //2.public string tostring(): 返回此可抛出的简短描述
            System.out.println("=============== 2.public string tostring(): 返回此可抛出的简短描述 ===============");
    
            //自己处理(捕获异常)
            try {
                System.out.println(arr[10]);//索引越界异常 ArrayIndexOutOfBoundsException
            } catch (ArrayIndexOutOfBoundsException e) {
                String str = e.toString();
                System.out.println(str);
            }
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
    
    
            //3.public void printstackTrace(): 用红色字体把异常的错误信息输出在控制台(仅仅是打印信息,不会停止虚拟机)
            System.out.println("=============== 3.public void printstackTrace(): 用红色字体把异常的错误信息输出在控制台(仅仅是打印信息,不会停止虚拟机) ===============");
    
            //自己处理(捕获异常)
            try {
                System.out.println(arr[10]);//索引越界异常 ArrayIndexOutOfBoundsException
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
        }
    }
    
    
  • 输出结果
    在这里插入图片描述

3. 异常分类

我们平常说的异常就是指Exception,因为这类异常一旦出现,我们就要对代码进行更正,修复程序。

异常(Exception)的分类:根据在编译时期还是运行时期去检查异常

  • 编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)

  • 运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)

在这里插入图片描述

4. 异常处理方式

4.1 JVM默认处理异常

JVM(Java虚拟机)具有默认的异常处理机制,用于处理在程序执行期间可能抛出的未捕获异常。

  • JVM默认处理异常的方式:
    1. 把异常的名称,异常原因及异常出现的位置等信息输出在了控制台

    2. 程序停止执行,异常下面的代码就不会再执行

需要注意的是,JVM的默认异常处理机制只能处理未捕获的异常。对于已经在代码中进行了捕获并做了处理的异常,JVM不会介入其中。

  • 代码示例
    package text.text02;
    
    /*
    JVM默认处理异常的方式:
        1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台
        2.程序停止执行,异常下面的代码就不会再执行
     */
    public class text82 {
        public static void main(String[] args) {
    
            System.out.println("aaaaa");
            System.out.println("bbbbb");
    
            //算术异常(ArithmeticException)
            System.out.println(10 / 0);
    
            System.out.println("ccccc");
            System.out.println("ddddd");
    
        }
    }
    
    
  • 输出结果
    在这里插入图片描述

4.2 自己处理(捕获异常)try...catch

4.2.1 概述
  • 目的:当代码出现异常时,可以让程序继续往下执行。

  • 在Java中,可以使用try...catch语句块来捕获和处理异常。

  • try...catch语句块的基本语法如下:

    try {
        // 可能会抛出异常的代码
    } catch (异常类型1 异常变量1) {
        // 处理异常类型1的代码
    } catch (异常类型2 异常变量2) {
        // 处理异常类型2的代码
    } finally {
        // 可选的finally代码块,无论是否发生异常,都会被执行
    }
    

try代码块包含了可能会抛出异常的代码。当异常发生时,Java虚拟机会立即停止当前代码块的执行,并跳转到catch代码块中,根据异常的类型与catch代码块中的异常类型进行匹配。

  • 如果匹配成功,则执行对应的catch代码块,进行异常处理。

  • 如果没有匹配的catch代码块,则异常将被传递到更高层的调用栈中,继续寻找匹配的catch代码块。

  • 如果找不到任何匹配的catch代码块,程序将会终止,并输出相关的异常信息。

catch代码块用于处理特定类型的异常。你可以在一个try结构中使用多个catch代码块,以处理不同类型的异常。每个catch代码块包含了异常类型和异常变量,异常变量用于引用被捕获的异常对象,以便进行进一步的处理。

finally代码块是可选的,用于定义无论是否发生异常,都会执行的代码。它一般被用于释放资源或进行清理操作。即使在trycatch代码块中有return语句,finally代码块仍然会在return之前执行。

  • 代码示例
    package text.text02;
    
    /*自己处理(捕获异常)
    格式:
        try {
            可能出现的异常;
        } catch (异常类名 变量名){
            异常的处理代码;
        }
    
    目的:当代码出现异常时,可以让程序继续往下执行。
    
     自己处理(捕获异常)灵魂四问:
        1.一问:如果try中没有遇见问题,怎么执行?
            答:如果try中没有遇见问题,会吧try里面的代码全部执行完毕,再继续执行try...catch体系下面的其他代码,而不会执行catch里面的代码
            注意:只有当出现了异常才会执行catch里面的代码。
    
        2.二问:如果try中可能遇见多个问题,怎么执行?
            答:如果try中可能遇见多个问题,一般需要写多个catch与之对应。
             try中代码会从上往下执行,如果try中有异常没有与catch对应,则会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)
    
            细节:如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面
    
            JDK7之后,可以在catch中同时捕获多个异常,中间用 | 隔开,表示如果出现了A异常或者B异常时,采用同一种处理方案
    
        3.三问:如果try中遇见的问题没有被捕获,怎么执行?
            答:如果try中遇见的问题没有被捕获,相当于try...catch体系白写了,Java会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)
    
        4.四问:如果try中遇见了问题,那么try下面的其他代码还会执行吗?
            答:如果try中遇见了问题,那么try下面的其他代码不会执行了,会直接跳转到catch当中,执行catch里面的代码。如果try中有异常没有与catch对应,则会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)
    
     */
    public class text83 {
        public static void main(String[] args) {
            int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
    
            //自己处理(捕获异常)
            try {
                System.out.println(arr[10]);//索引越界异常 ArrayIndexOutOfBoundsException
                //此处出现了异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException(索引越界异常)对象(new ArrayIndexOutOfBoundsException());拿着这个对象到catch的小括号中对比,看括号中的变量是否可以接受这个对象。如果可以被接受,就表示该异常被捕获(抓住),执行catch里面对应的代码。当catch里面的所有的代码都执行完毕,继续执行try...catch体系下面的其他代码
    
                //异常类名: ArrayIndexOutOfBoundsException
                //变量名: e
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("索引越界异常!" + e);
            }
    
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
        }
    }
    
    
  • 输出结果
    在这里插入图片描述
4.2.2 灵魂四问

自己处理(捕获异常)灵魂四问:

  1. 一问:如果try中没有遇见问题,怎么执行?

    • 答:如果try中没有遇见问题,会吧try里面的代码全部执行完毕,再继续执行try…catch体系下面的其他代码,而不会执行catch里面的代码

    • 注意:只有当出现了异常才会执行catch里面的代码。

  2. 二问:如果try中可能遇见多个问题,怎么执行?

    • 答:如果try中可能遇见多个问题,一般需要写多个catch与之对应。

    • try中代码会从上往下执行,如果try中有异常没有与catch对应,则会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)

    • 细节:如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面

    • JDK7之后,可以在catch中同时捕获多个异常,中间用 | 隔开,表示如果出现了A异常或者B异常时,采用同一种处理方案

  3. 三问:如果try中遇见的问题没有被捕获,怎么执行?

    • 答:如果try中遇见的问题没有被捕获,相当于try…catch体系白写了,Java会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)
  4. 四问:如果try中遇见了问题,那么try下面的其他代码还会执行吗?

    • 答:如果try中遇见了问题,那么try下面的其他代码不会执行了,会直接跳转到catch当中,执行catch里面的代码。如果try中有异常没有与catch对应,则会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)
  • 代码示例1:一问:如果try中没有遇见问题,怎么执行?

    package text.text02;
    
    /*
     自己处理(捕获异常)灵魂四问:
        一问:如果try中没有遇见问题,怎么执行?
          答:如果try中没有遇见问题,会吧try里面的代码全部执行完毕,再继续执行try...catch体系下面的其他代码,而不会执行catch里面的代码
            注意:只有当出现了异常才会执行catch里面的代码。
     */
    public class text84 {
        public static void main(String[] args) {
            int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
    
            //自己处理(捕获异常)
            try {
                System.out.println(arr[0]);
                System.out.println("try里面的代码执行了");
    
                //异常类名: ArrayIndexOutOfBoundsException
                //变量名: e
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("索引越界异常!" + e);
            }
    
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
        }
    }
    
    
  • 输出结果1
    在这里插入图片描述

  • 代码示例2:二问:如果try中可能遇见多个问题,怎么执行?

    package text.text02;
    
    /*
     自己处理(捕获异常)灵魂四问:
     二问:如果try中可能遇见多个问题,怎么执行?
          答:如果try中可能遇见多个问题,一般需要写多个catch与之对应。
             try中代码会从上往下执行,如果try中有异常没有与catch对应,则会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)
    
          细节:如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面
    
          JDK7之后,可以在catch中同时捕获多个异常,中间用 | 隔开,表示如果出现了A异常或者B异常时,采用同一种处理方案
     */
    public class text85 {
        public static void main(String[] args) {
            int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
    
            //JDK7以前
            System.out.println("JDK7以前:");
            //自己处理(捕获异常)
            try {
                System.out.println(10 / 0);//算术异常 ArithmeticException
                System.out.println(arr[10]);//索引越界异常 ArrayIndexOutOfBoundsException
    
                String str = null;
                System.out.println(str.equals("aaa"));//空指针异常 NullPointerException
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("索引越界异常!" + e);
            } catch (ArithmeticException e) {
                System.out.println("算术异常!" + e);
            } catch (NullPointerException e) {
                System.out.println("空指针异常!" + e);
            }
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
    
    
            //JDK7之后,可以在catch中同时捕获多个异常,中间用 | 隔开,表示如果出现了A异常或者B异常时,采用同一种处理方案
            System.out.println("JDK7以后:");
            try {
                System.out.println(10 / 0);//算术异常 ArithmeticException
                System.out.println(arr[10]);//索引越界异常 ArrayIndexOutOfBoundsException
    
                String str = null;
                System.out.println(str.equals("aaa"));//空指针异常 NullPointerException
            } catch (ArrayIndexOutOfBoundsException | ArithmeticException | NullPointerException e) {
                System.out.println("出现异常!" + e);
            }
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
        }
    }
    
    
  • 输出结果2
    在这里插入图片描述

  • 代码示例3:三问:如果try中遇见的问题没有被捕获,怎么执行?

    package text.text02;
    
    /*
     自己处理(捕获异常)灵魂四问:
      三问:如果try中遇见的问题没有被捕获,怎么执行?
        答:如果try中遇见的问题没有被捕获,相当于try...catch体系白写了,Java会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)
     */
    public class text86 {
        public static void main(String[] args) {
    
            //自己处理(捕获异常)
            try {
                System.out.println(10 / 0);//算术异常 ArithmeticException
    
            } catch (ArrayIndexOutOfBoundsException e) { //索引越界异常  ArrayIndexOutOfBoundsException
                System.out.println("索引越界异常!" + e);
            }
    
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
        }
    }
    
    
  • 输出结果3
    在这里插入图片描述

  • 代码示例4:四问:如果try中遇见了问题,那么try下面的其他代码还会执行吗?

    package text.text02;
    
    /*
    自己处理(捕获异常)灵魂四问:
    四问:如果try中遇见了问题,那么try下面的其他代码还会执行吗?
      答:如果try中遇见了问题,那么try下面的其他代码不会执行了,会直接跳转到catch当中,执行catch里面的代码。如果try中有异常没有与catch对应,则会默认采取JVM默认处理异常的方式(1.把异常的名称,异常原因及异常出现的位置等信息输出在了控制台 2.程序停止执行,异常下面的代码就不会再执行)
    */
    public class text87 {
        public static void main(String[] args) {
            //自己处理(捕获异常)
            try {
                System.out.println(10 / 0);//算术异常 ArithmeticException
                System.out.println("try里面的代码执行了");
            } catch (ArithmeticException e) {
                System.out.println("算术异常!" + e);
            }
            //检验代码是否执行到这一步
            System.out.println("try...catch体系外的代码执行了");
        }
    }
    
    
  • 输出结果4
    在这里插入图片描述

4.3 抛出处理(throw和throws)

在Java中,throwthrows是用于异常处理的关键字,用于处理和传递异常。

  1. throw关键字:
    • 使用throw关键字可以手动抛出一个异常。你可以将任何继承自Throwable类的异常对象抛出。

    • throw语句通常放在条件语句或代码块中,用于在特定情况下抛出异常。

    • 抛出异常将程序的控制权交给上层调用栈,直到找到合适的异常处理器来处理异常。

    • 使用throw抛出的异常可以是受检查异常也可以是非受检查异常。

  • throw:写在方法内,结束方法,手动抛出异常对象,交给调用者,方法下面的代码不再执行了

    • 格式:
    throw new 异常类名(参数);
    
    • 举例:
    throw new NullPointerException("要访问的arr数组不存在");
    throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围");
    
  1. throws关键字:
    • throws关键字用于声明一个方法可能抛出的异常类型。
    • 在方法声明中,可以使用throws关键字后跟一个异常类型或异常类型的列表,多个异常类型之间用逗号分隔。
    • 声明throws的作用是告知调用者方法可能抛出的异常,以让调用者知道需要进行相应的异常处理或继续将异常传递给上层代码。
    • 如果一个方法声明了抛出异常,而调用者没有进行处理或继续传递,那么调用者也必须使用throws关键字声明进行处理。
  • throws: 写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常

    • 格式:
    修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2{   }
    
    • 举例:
    public void 方法() throws 异常类名1,异常类名2...{
    	 ...
     }
    
      · 编译时异常:必须手写
      · 运行时异常:可以省略
    
  • 代码示例
    练习:定义一个方法求数组的最大值

    package text.text02;
    
    /*抛出处理:
    throws: 写在方法定义处,表示声明一个异常,告诉调用者,使用本方法可能会有哪些异常
        格式:修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{   }
        举例:public void 方法() throws 异常类名1,异常类名2...{
                 ...
             }
        · 编译时异常:必须手写
        · 运行时异常:可以省略
    
    throw:写在方法内,结束方法,手动抛出异常对象,交给调用者,方法下面的代码不再执行了
        格式:throw new 异常类名(参数);
        举例:throw new NullPointerException("要访问的arr数组不存在");
             throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围");
    
    练习:定义一个方法求数组的最大值
     */
    public class text89 {
        public static void main(String[] args) {
            int[] arr = {1, 2, 3, 4, 56, 7, 8, 9, 10, 5, 6};
            int[] arr1 = null;
            int[] arr2 = {};
    
            int max = 0;
            int max1 = 0;
            int max2 = 0;
    
            //捕获异常
            try {
                max = getMax(arr);
                max1 = getMax(arr1);
                max2 = getMax(arr2);
            } catch (NullPointerException | IndexOutOfBoundsException e) {
                e.printStackTrace();
            }
    
            System.out.println(max);
            System.out.println(max1);
            System.out.println(max2);
        }
    
        public static int getMax(int[] arr) /* throws NullPointerException,IndexOutOfBoundsException*/ { //运行时异常:可以省略
            if (arr == null) {
                //手动创建一个异常对象,并把这个异常交给方法的调用者处理,此时方法就会结束,下面的代码不会再执行了
                throw new NullPointerException();//空指针异常  NullPointerException
            }
            if (arr.length == 0) {
                //手动创建一个异常对象,并把这个异常交给方法的调用者处理,此时方法就会结束,下面的代码不会再执行了
                throw new IndexOutOfBoundsException();//索引越界异常  IndexOutOfBoundsException
            }
            int max = arr[0];
            for (int i : arr) {
                if (i > max) {
                    max = i;
                }
            }
            return max;
        }
    }
    
    
  • 输出结果
    在这里插入图片描述

5. 自定义异常

5.1 概述

在Java中,可以通过自定义异常来创建特定的异常类型,以便更好地处理和标识特定的异常情况。

自定义异常允许定义具有特定行为和属性的异常类,用于在程序中抛出和捕获异常。

  • 目的:为了让控制台的报错信息更加的见名之意

  • 步骤:

    1. 定义异常类

    2. 写继承关系

    3. 空参构造

    4. 带参构造

5.2 代码示例

  • 代码示例
    • 练习:键盘录入数据:

    • 需求:

      • 1.键盘录入自己心仪的女朋友姓名和年龄,

      • 2.姓名的长度在3-10之间,

      • 3.年龄的范围为 18-40岁

      • 4.超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。

    • 提示: 需要考虑用户在键盘录入时的所有情况。

      • 比如:录入年龄时超出范围,录入年龄时录入了abc等情况
      package text.text02;
      
      import java.util.Scanner;
      
      /*
      自定义异常:
      目的:为了让控制台的报错信息更加的见名之意
      
      步骤:1.定义异常类
           2.写继承关系
           3.空参构造
           4.带参构造
      
      
      练习:
          键盘录入数据:
          需求:1.键盘录入自己心仪的女朋友姓名和年龄,
               2.姓名的长度在3-10之间,
               3.年龄的范围为 18-40岁
               4.超出这个范围是异常数据不能赋值,需要重新录入,一直录到正确为止。
          提示:
              需要考虑用户在键盘录入时的所有情况。
              比如:录入年龄时超出范围,录入年龄时录入了abc等情况
       */
      public class text91 {
          public static void main(String[] args) {
              //空参创建学生对象
              girlFriend1 gf = new girlFriend1();
              //键盘录入
              Scanner sc = new Scanner(System.in);
              while (true) {
                  //捕获异常
                  try {
                      System.out.println("请输入姓名:");
                      String name = sc.nextLine();
                      gf.setName(name);
                      System.out.println("请输入年龄:");
                      String ageString = sc.nextLine();
                      int age = Integer.parseInt(ageString);
                      gf.setAge(age);
                      //如果所有的数据都是正确的,跳出循环
                      break;
                  } catch (NumberFormatException e) {
                      System.out.println("年龄的格式有误,请输入数字!");
                      e.printStackTrace();
                  } catch (nameFormatException e) {
                      e.printStackTrace();
                  } catch (ageOutOfBoundsException e) {
                      e.printStackTrace();
                  }
              }
      
              System.out.println(gf.getName() + " , " + gf.getAge());
      
          }
      }
      
      //自定义姓名格式化异常
      class nameFormatException extends RuntimeException {
          public nameFormatException() {
          }
      
          public nameFormatException(String message) {
              super(message);
          }
      }
      
      //自定义年龄格式化异常
      class ageOutOfBoundsException extends RuntimeException {
          public ageOutOfBoundsException() {
          }
      
          public ageOutOfBoundsException(String message) {
              super(message);
          }
      }
      
      
      class girlFriend1 {
          private String name;
          private int age;
      
          public girlFriend1() {
          }
      
          public girlFriend1(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          /**
           * 获取
           *
           * @return name
           */
          public String getName() {
              return name;
          }
      
          /**
           * 设置
           *
           * @param name
           */
          public void setName(String name) {
              if (name.length() < 3 || name.length() > 10) {
                  throw new nameFormatException("姓名的长度有误!");
              } else {
                  this.name = name;
              }
          }
      
          /**
           * 获取
           *
           * @return age
           */
          public int getAge() {
              return age;
          }
      
          /**
           * 设置
           *
           * @param age
           */
          public void setAge(int age) {
              if (age < 18 || age > 40) {
                  throw new ageOutOfBoundsException("年龄的范围有误!");
              } else {
                  this.age = age;
              }
          }
      
          public String toString() {
              return "girlFriend{name = " + name + ", age = " + age + "}";
          }
      }
      
      
      
  • 输出结果
    在这里插入图片描述

6. 异常注意事项

  1. 运行时异常被抛出可以不处理。即不捕获也不声明抛出。

  2. 如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集。

  3. 父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出

  4. 当多异常处理时,捕获处理,前边的类不能是后边类的父类

  5. 在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1448120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GPT-4影响高度创新思维的领域(一)

GPT-4的应用范围不再局限于对现有信息的检索、整理和复述&#xff0c;而是进一步拓展到了诸如文学创作、科学假设生成、教育辅导、商业策略建议等需要高度创新思维的领域。这种独立思考和创新能力赋予了GPT-4作为虚拟助手时更加丰富多元的角色定位&#xff0c;使其成为一种强大…

如何在PDF 文件中删除页面?

查看不同的工具以及解释如何在 Windows、Android、macOS 和 iOS 上从 PDF 删除页面的步骤&#xff1a; PDF 是最难处理的文件格式之一。曾经有一段时间&#xff0c;除了阅读之外&#xff0c;无法用 PDF 做任何事情。但是今天&#xff0c;有许多应用程序和工具可以让您用它们做…

寒假思维训练day21

今天更新一道不错的状态压缩DP题&#xff0c;顺带总结一下状态压缩DP。 摘要&#xff1a; Part1 浅谈状态压缩DP的理解 Part2 浅谈对状态机DP的理解 Part3 关于状态压缩DP的1道例题 Part1 状态压缩DP 1、状态压缩DP&#xff1a; 事物的状态可能包含多个特征&#xff0c;…

Zotero插件分享(第二弹)

今天紧接上一篇文章&#xff08;Zotero常用插件分享&#xff09;&#xff0c;继续分享关于Zotero常用插件的相关内容。&#xff08;排名不分先后&#xff09; 1.Translate for Zotero 英文文献阅读辅助工具&#xff0c;可以实现将pdf中选中的文字翻译为指定语言&#xff0c;并…

【学网攻】 第(27)节 -- HSRP(热备份路由器协议)

系列文章目录 目录 系列文章目录 文章目录 前言 一、HSRP(热备份路由器协议)是什么&#xff1f; 二、实验 1.引入 实验目标 实验背景 技术原理 实验步骤 实验设备 实验拓扑图 实验配置 实验验证 文章目录 【学网攻】 第(1)节 -- 认识网络【学网攻】 第(2)节 -- 交…

港口码头航吊远距离相位测距仪|传感器PHR-120100配置使用说明

港口码头航吊远距离相位测距仪|传感器PHR-120100广泛应用于港口码头、航车、位移监测、形变监测、钢铁、堆垛机、龙门吊等领域。 本文重点介绍港口码头航吊远距离相位测距仪|传感器PHR-120100配置使用说明。 一、布局介绍 二、按键介绍 三、指示灯说明 四、显示屏操作说明 …

使用LORA微调RoBERTa

模型微调是指在一个已经训练好的模型的基础上&#xff0c;针对特定任务或者特定数据集进行再次训练以提高性能的过程。微调可以在使其适应特定任务时产生显着的结果。 RoBERTa&#xff08;Robustly optimized BERT approach&#xff09;是由Facebook AI提出的一种基于Transfor…

【EAI 020】Diffusion Policy: Visuomotor Policy Learning via Action Diffusion

论文标题&#xff1a;Diffusion Policy: Visuomotor Policy Learning via Action Diffusion 论文作者&#xff1a;Cheng Chi, Siyuan Feng, Yilun Du, Zhenjia Xu, Eric Cousineau, Benjamin Burchfiel, Shuran Song 作者单位&#xff1a;Columbia University, Toyota Research…

C#中implicit和explicit

理解: 使用等号代替构造函数调用的效果以类似重载操作符的形式定义用于类型转换的函数前者类型转换时候直接写等号赋值语法,后者要额外加目标类型的强制转换stirng str -> object o -> int a 可以 int a (int)(str as object)转换通过编译,但没有转换逻辑所以运行会报错…

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核基础-事件event

目录 一、事件基本概念二、事件运行机制三、事件开发流程四、事件使用说明五、事件接口坚持就有收获 一、事件基本概念 事件是一种实现任务间通信的机制&#xff0c;可用于实现任务间的同步&#xff0c;但事件通信只能是事件类型的通信&#xff0c;无数据传输。一个任务可以等…

LeetCode、452. 用最少数量的箭引爆气球【中等,贪心,区间问题】

文章目录 前言LeetCode、452. 用最少数量的箭引爆气球【中等&#xff0c;贪心&#xff0c;区间问题】题目链接与分类思路贪心&#xff0c;连续区间数量问题 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客…

带你掌握getchar与putchar的基本用法

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 目录 getcahr putchar getchar 与 putchar 的配合使用 getchar相较于scanf的优缺点 putchar相较于printf的优缺点 getcahr 函数原型&#xff1a…

【教程】MySQL数据库学习笔记(二)——数据类型(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 文章目录 【MySQL数据库学习】系列文章一、整…

DFM-无监督图像匹配

DFM&#xff1a;A Performance Baseline for Deep Feature Matching&#xff08;深度特征匹配的性能基准&#xff09; 2021.06.14 摘要 提出了一种新的图像匹配方法&#xff0c;利用现成的深度神经网络提取的学习特征来获得良好的图像匹配效果。该方法使用预训练的VGG结构作为…

starknet之 class_hash

文章目录 问题背景什么是Class Hash问题背景 部署合约报错:ReferenceError: Buffer is not defined 什么是Class Hash 官方: https://book.starknet.io/ch04-03-01-deploy-standard-account.html?highlight=class%20hash#finding-the-class-hash 要部署智能合约,您需要在…

【原创 附源码】Flutter集成Apple支付详细流程(附源码)

最近有时间&#xff0c;特意整理了一下之前使用过的Flutter平台的海外支付&#xff0c;附源码及demo可供参考 这篇文章只记录Apple支付的详细流程&#xff0c;其他相关Flutter文章链接如下&#xff1a; 【原创 附源码】Flutter集成谷歌支付详细流程(附源码) 【原创 附源码】F…

PR:熟悉PR工作环境

新建项目 设置自己的页面布局 首选项

【JavaEE】_JavaScript基础语法

目录 1. JavaScript概述 1.1 JavaScript简介 1.2 HTML、CSS、JavaScript的关系 1.3 JavaScrip的组成 2. JavaScript的书写形式 2.1 内嵌式 2.2 行内式 2.3 外部式 3. 输出 3.1 alert 3.2 console.log 4. 变量的使用 4.1 创建变量 4.1.1 使用var 4.1.2 使用let …

java中事务的使用

文章目录 前言一、同一张表1.业务代码2.测试代码3.测试结果 二、不同表1.业务代码2.测试代码3.测试结果 总结 前言 本文将介绍在springboot中使用Transactional注解来完成对数据库事务的操作&#xff0c;保证数据一致性。 一、同一张表 1.业务代码 Controller Controller p…

停止内耗,做有用的事

很多读者朋友跟我交流的时候&#xff0c;都以为我有存稿&#xff0c;于是听到我说每周四现写的时候都很惊讶。其实没什么好惊讶的&#xff0c;每周四我都会把自己关在书房里一整天&#xff0c;断掉一切电话、微信、邮件&#xff0c;从中午写到晚上&#xff0c;直到写完为止。 这…