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);
    }
}

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("程序结束");
    }

}

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("请输入正确的数字!");
        }

    }

}

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("分母不能为零!");
        }
    }

}

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("程序结束");
    }

}

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("程序结束");
    }

}

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("程序结束");
    }

}

8. 抛出异常

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

// 省略导包和主类声明

public class Test07 {
    public static void main(String[] args) throws Exception {
        throw new Exception();
    }
}

9. 使用 throws 声明异常

在方法中,我们可以使用throws关键字来声明可能抛出的异常,这样调用者就知道需要处理这些异常。

// 省略导包和主类声明

```java
// 省略导包和主类声明

public class Test08 {
    public static void main(String[] args) {
        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("成绩不能为负数!");
        System.out.println("成绩:" + cj);
    }

    public static void f02(int cj) {
        if (cj < 0) throw new RuntimeException("成绩不能为负数!");
        System.out.println("成绩:" + cj);
    }
}

10. 递归导致堆栈溢出

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

// 省略导包和主类声明

public class Test09 {
    public static void main(String[] args) {
        main(args); // 这会导致 java.lang.StackOverflowError
        System.out.println("结束!");
    }
}

11. 自定义异常

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

// 省略导包和主类声明

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("性别正确");
    }
}

总结

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

你可能感兴趣的:(从零开始学JAVA,开发语言,java)