• Java面向对象学习笔记-4


    前言

    当编写Java程序时,了解如何处理异常是至关重要的。异常处理可以帮助我们在程序执行过程中处理各种错误情况,以确保程序能够正常运行或者 graceful 地退出。本文将介绍一些关于Java异常处理的基本概念和最佳实践,包括自定义异常类、用户输入的处理、异常捕获与处理、打印异常信息、使用 try-catch-finally 结构、异常捕获的顺序、抛出异常、使用 throws 声明异常、递归导致堆栈溢出,以及自定义异常。
    Java面向对象学习笔记-1
    Java面向对象学习笔记-2
    Java面向对象学习笔记-3

    1. 自定义异常类

    首先,让我们看看如何创建自定义异常类。在Java中,我们可以继承内置的Exception类来创建我们自己的异常类。这个自定义异常类可以用于抛出和捕获自定义异常。

    package cn.dfjy.demo;
    
    public class MyException extends Exception {
    
        public MyException(String msg) {
            super(msg);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2. 基本用户输入

    用户输入是大多数Java应用程序的一部分。下面是如何使用Scanner类从控制台读取用户输入的整数的示例。

    package cn.dfjy.demo;
    
    import java.util.Scanner;
    
    public class Test {
        public static void main(String[] args) {
            //System.out.println(args[0]);
            Scanner scanner = new Scanner(System.in);
    
            /*
            异常也是一个类
            java.util.InputMismatchException
            java.lang.NullPointerException
            java.lang.ArrayIndexOutOfBoundsException
            java.lang.ArithmeticException
             */
            System.out.println("请输入一个数字:");
            int number = scanner.nextInt();
            System.out.println("数字是:" + number);
    
            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

    3. 异常处理基础

    在处理用户输入时,我们需要验证用户是否提供了正确的数据类型。这可以使用hasNextInt()方法来实现。

    package cn.dfjy.demo;
    
    import java.util.Scanner;
    
    public class Test02 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            /*
                解决异常的思路:
                    使用if判断
             */
            System.out.println("请输入一个数字:");
            if (scanner.hasNextInt()) { // 判断是否缓冲区(键盘)接收到一个数字
                int number = scanner.nextInt();
                System.out.println("数字是:" + number);
            } else {
                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

    4. 使用 Try-Catch 处理异常

    异常是可能发生的错误的标志,我们可以使用try-catch块来处理异常,以确保程序在遇到问题时不会崩溃。

    package cn.dfjy.demo;
    
    import java.util.InputMismatchException;
    import java.util.Scanner;
    
    public class Test03 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            /*
                解决异常的思路:
                    使用异常机制 try catch
             */
            try {
                System.out.println("请输入一个数字(分子):");
                int number1 = scanner.nextInt();
                System.out.println("请输入一个数字(分母):");
                int number2 = scanner.nextInt();
                System.out.println(number1 + "/" + number2 + "=" + number1/number2);
            } catch (InputMismatchException ex) {
                System.out.println("请输入正确的数字!");
            } catch (ArithmeticException ex) {
                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

    5. 打印异常信息

    在异常处理中,我们通常希望能够记录或打印异常的详细信息,以便进行调试和追踪问题。

    package cn.dfjy.demo;
    
    import java.util.InputMismatchException;
    import java.util.Scanner;
    
    public class Test04 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            /*
                解决异常的思路:
                    使用异常机制 try catch
             */
            try {
                System.out.println("请输入一个数字(分子):");
                int number1 = scanner.nextInt();
                System.out.println("请输入一个数字(分母):");
                int number2 = scanner.nextInt();
                System.out.println(number1 + "/" + number2 + "=" + number1/number2);
            } catch (InputMismatchException ex) {
                ex.printStackTrace(); // 打印异常的栈信息
                // System.out.println(ex.getMessage()); // 打印异常的信息:null
            } catch (ArithmeticException ex) {
                // ex.printStackTrace(); // 打印异常的栈信息
                System.out.println(ex.getMessage()); // 打印异常的信息:/ by zero
            }
    
            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

    6. 使用 Try-Catch-Finally 处理异常

    在某些情况下,我们需要确保资源得到正确释放,即使发生异常也不例外。这时,我们可以使用try-catch-finally结构。

    package cn.dfjy.demo;
    
    import java.util.InputMismatchException;
    import java.util.Scanner;
    
    public class Test05 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            /*
                解决异常的思路:
                    使用异常机制 try catch finally
                    面试:
                    1. finally代码块不执行的唯一条件
                       虚拟机结束
             */
            try {
                System.out.println("请输入一个数字(分子):");
                int number1 = scanner.nextInt();
                System.out.println("请输入一个数字(分母):");
                int number2 = scanner.nextInt();
                System.out.println(number1 + "/" + number2 + "=" + number1/number2);
                System.exit(0); // Terminates the currently running Java Virtual Machine 结束当前java虚拟机
                System.out.println("return");
                return; // 也挡不住 finally 的执行
            } catch (InputMismatchException ex) {
                System.out.println(ex.getMessage()); // 打印异常的信息:null
            } catch (ArithmeticException ex) {
                System.out.println(ex.getMessage()); // 打印异常的信息:/ by zero
            } finally {
                // 最终
                System.out.println("try块中涉及的资源释放");
            }
    
            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
    • 38
    • 39

    7. 异常捕获顺序

    Java允许我们捕获多个异常,但需要注意它们的顺序。Java会选择第一个匹配的catch块执行,因此catch块的顺序很重要。

    package cn.dfjy.demo;
    
    import java.util.InputMismatchException;
    import java.util.Scanner;
    
    public class Test06 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            /*
                解决异常的思路:
                    使用异常机制 try catch finally
                    catch顺序
                    1. 没有继承关系的,谁先谁后,都可以
                    2. 有继承关系的,记住父亲在后 Exception 兜底
             */
            try {
                System.out.println(args[0]);
                System.out.println("请输入一个数字(分子):");
                int number1 = scanner.nextInt();
                System.out.println("请输入一个数字(分母):");
                int number2 = scanner.nextInt();
                System.out.println(number1 + "/" + number2 + "=" + number1/number2);
            } catch (ArithmeticException ex) {
                System.out.println(ex.getMessage()); // 打印异常的信息:/ by zero
            } catch (InputMismatchException ex) {
                System.out.println(ex.getMessage()); // 打印异常的信息:null
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
            } finally {
                // 最终
                System.out.println("try块中涉及的资源释放");
            }
    
            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
    • 38
    • 39

    8. 抛出异常

    在Java中,我们可以使用throw关键字在方法中抛出异常。

    package cn.dfjy.demo;
    
    import java.util.Scanner;
    
    public class Test07 {
        public static void main(String[] args) throws Exception {
            Scanner scanner = new Scanner(System.in);
    
            /*
                解决异常的思路:
                    使用异常机制 try catch finally throw throws
    
                    throw,用于方法体内代码行
                    throws,用于方法声明上,跟在方法的后面一点
             */
            throw new Exception();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    9. 使用 throws 声明异常

    在方法中,我们可以使用throws关键字来声明可能抛出的异常,这样调用者就知道需要处理这些异常。
    Java中的异常,可以被分为两大类:必检异常(checked exceptions)和运行期异常(unchecked exceptions)。

    1. 必检异常(Checked Exceptions)

      • 这些异常是在编译时强制要求处理的异常,必须要么使用 try-catch 块捕获,要么在方法签名中使用 throws 关键字声明抛出异常。
      • 通常用于表示程序可能遇到的外部因素导致的问题,如文件不存在、网络连接问题等。
      • 例子:IOException, SQLException, ClassNotFoundException等。
    2. 运行期异常(Unchecked Exceptions)

      • 这些异常通常是由程序逻辑错误引起的,不需要在编译时强制处理。
      • 通常用于表示编程错误,如空指针异常、数组越界异常等。
      • 例子:NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException等。

    要选择使用哪种异常类型取决于异常的性质。如果异常是由于无法控制的外部因素引起的,应该使用必检异常。如果异常是由于程序错误引起的,通常使用运行期异常。这有助于提高代码的可读性和维护性,并帮助开发人员更好地处理异常情况。

    package cn.dfjy.demo;
    
    import java.util.Scanner;
    
    public class Test08 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            /*
                解决异常的思路:
                    使用异常机制 try catch finally throw throws
    
                    throw,用于方法体内代码行
                    throws,用于方法声明上,跟在方法的后面一点
             */
            try {
                f01(-100);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
    
            f02(-100);
    
            System.out.println("代码正常走完");
        }
    
        public static void f01(int cj) throws Exception {
            if (cj < 0) throw new Exception("成绩不能为负数!"); // 必检异常(排除掉RuntimeException或它的子类)
            System.out.println("成绩:" + cj);
        }
    
        public static void f02(int cj) {
            if (cj < 0) throw new RuntimeException("成绩不能为负数!"); // 运行期异常
            System.out.println("成绩:" + cj);
        }
    
    }
    
    
    • 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

    当你编写Java程序时,有时候会出现一些问题或错误,这些问题被称为异常。异常可能有不同的类型,而这两个函数 f01f02 就是在处理异常时有所不同的例子。

    1. f01 函数抛出的是一个叫做 “必检异常” 的问题。这就像你在写作业时,如果有一个问题你必须解决它,否则你的作业就不会通过。在这个情况下,你必须处理这个异常,要么使用特殊的代码(try-catch),要么告诉其他人(方法签名中的 throws)这个问题可能会出现。

    2. f02 函数抛出的是一个叫做 “运行期异常” 的问题。这就像你在玩游戏时,如果你犯了一个小错误,游戏不会立刻停止,但会给你一个警告。在这个情况下,你可以选择处理这个问题,但不是必须的,程序不会因为这个问题而立刻停止。

    所以,主要区别是对待这些异常的方式。必检异常需要你在代码中明确处理,而运行期异常则是可选择性的。你可以根据问题的性质选择使用哪种异常类型。

    10. 递归导致堆栈溢出

    递归是一种有用的编程技巧,但如果没有正确的终止条件,它可能导致堆栈溢出。

    package cn.dfjy.demo;
    
    public class Test09 {
        public static void main(String[] args) {
            main(args); // java.lang.StackOverflowError
            System.out.println("结束!");
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    11. 自定义异常

    最后,我们可以创建自己的自定义异常,并在方法中抛出它,然后在main方法中捕获和处理它。

    package cn.dfjy.demo;
    
    public class Test10 {
        public static void main(String[] args) {
            try {
                f01("公");
            } catch (MyException e) {
                System.out.println(e.getMessage());
            }
    
            System.out.println("正常结束");
        }
    
        public static void f01(String sex) throws MyException {
            if (!"男".equals(sex) && !"女".equals(sex)) throw new MyException("性别必须是男或女");
            System.out.println("性别正确");
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    总结

    这些示例提供了关于Java异常处理的基本概念和实际应用。通过学习这些示例,你可以更好地理解如何使用异常处理来构建健壮的Java程序。异常处理是编写高质量、可维护的代码的关键部分,因此确保掌握这些概念是很有价值的。

  • 相关阅读:
    leetcodeTop100(21) 相交链表
    哈希应用之位图
    【Java学习】JDK安装及第一个java程序
    java毕业设计企业级工位管理系统mybatis+源码+调试部署+系统+数据库+lw
    SpringMVC学习笔记(十一)—— 拦截器
    数据分析:单元2 NumPy数据存取与函数
    Linux/centos上如何配置管理Web服务器?
    MyBatis关系映射
    古人的雅趣
    它把RabbitMQ的复杂全屏蔽了,我朋友用它后被老板一夜提拔为.NET架构师
  • 原文地址:https://blog.csdn.net/qq_42531954/article/details/132818719