【JAVA】part3-Java异常处理

本文详细介绍了Java中的异常处理机制,包括检查型异常和非检查型异常的区别,try-catch-finally结构,以及如何使用throw和throws关键字。同时探讨了Log4j日志框架及其组件。通过实例展示了异常处理的最佳实践和Log4j的配置原理。
摘要由CSDN通过智能技术生成

异常处理

ExceptionIntro.java
ExceptionCalculate.java
异常处理是Java编程语言中管理和解决运行时错误的一种重要机制。它使得程序可以在遇到异常情况时优雅地恢复,而不是崩溃。以下是对Java异常处理机制的介绍:

  1. 异常类型:

    • 检查型异常(Checked Exceptions): 必须显式处理的异常,否则程序无法编译。这些异常通常是在编写安全的可恢复代码时应该捕获的。
    • 非检查型异常(Unchecked Exceptions): 包括运行时异常(RuntimeException)和错误(Error)。这些异常通常是编程错误(如数组越界)或硬件错误(如内存溢出)。
  2. 关键字:

    • try: 放置可能会产生异常的代码块。
    • catch: 捕获并处理特定类型或多种类型的异常。
    • finally: 无论是否发生异常,此块中的代码都将执行,常用于清理资源。
    • throw: 用于主动抛出异常实例。
    • throws: 用于在方法签名中声明一个方法可能抛出的异常类型。
  3. 异常处理流程:

    • 当在 try 块中发生异常时,正常的控制流程会被中断。
    • 程序会尝试找到匹配的 catch 块来处理这个异常。
    • 如果找到匹配的 catch 块,该块中的代码将执行。
    • 无论是否找到匹配的 catch 块,finally 块(如果有的话)都将执行。
    • 如果没有找到匹配的 catch 块,异常会向上传播到调用栈中的前一个方法。
  4. 异常处理实践:

    • 捕获异常时,应尽量具体,不要捕获 Exception 类,除非有特殊需要。
    • 避免使用异常处理来控制程序流程。
    • finally 块中释放资源,例如关闭文件或数据库连接。
    • 尽量不要在 finally 块中使用 return 或抛出异常。
    • 使用自定义异常来提供更多错误信息,如果标准异常类不足以描述特定的错误情况。
  5. 常见异常类型:
    下表列出了一些Java中常见的异常类型及其简短描述:

异常类型描述
NullPointerException尝试使用 null 对象引用访问类的成员时抛出。
ArrayIndexOutOfBoundsException尝试访问数组时使用了非法索引(索引负数或大于等于数组大小)时抛出。
ArithmeticException发生异常的算术条件时抛出,例如除以零。
NumberFormatException尝试将字符串转换成数字格式,但字符串不具有适当的格式时抛出。
ClassCastException尝试将对象强制转换为不是实例的类时抛出。
IOException输入输出操作失败或中断时抛出,如读写文件时。
FileNotFoundException尝试打开指定路径名表示的文件失败时抛出,因为文件不存在。
InterruptedException线程在活动时被另一个线程中断时抛出。
NoSuchMethodException请求的方法不存在时抛出。
NoSuchFieldException请求的字段不存在时抛出。

ExceptionIntro.java

public class ExceptionIntro {
    public static void main(String[] args) {
        // 此处用于编写测试代码
    }
}

// 示例 1:捕获特定类型的异常
class DivisionExample {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("结果是: " + result);
        } catch (ArithmeticException e) {
            System.out.println("发生算术异常: 不能除以零.");
        }
    }

    public static int divide(int numerator, int denominator) {
        return numerator / denominator;
    }
}

// 示例 2:捕获所有异常
class CatchAllExample {
    public static void main(String[] args) {
        try {
            int[] numbers = {1, 2, 3};
            System.out.println(numbers[3]); // 这将抛出 ArrayIndexOutOfBoundsException
        } catch (Exception e) {
            System.out.println("发生异常: " + e.toString());
        }
    }
}


// 示例 3:使用 finally 关键字
class FinallyExample {
    public static void main(String[] args) {
            try {
                int[] numbers = {1, 2, 3};
                System.out.println(numbers[1]);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组索引越界");
            } finally {
                System.out.println("这段代码总会执行");
            }
        }
}


// 示例 4:使用 throws 关键字声明异常
class ThrowsExample {
    public static void main(String[] args) {
        try {
            myMethod();
        } catch (Exception e) {
            System.out.println("处理异常: " + e.getMessage());
        }
    }

    public static void myMethod() throws Exception {    // 在方法定义的时候,使用throws Xxx表示该方法可能抛出的异常类型。
        throw new Exception("我的异常被抛出了");
    }
}

ExceptionCalculate.java

/*
* 处理了用户输入非数字的情况,捕获 `InputMismatchException`。
* 使用 `ArithmeticException` 捕获了除法中的除零操作。
* 新增的 `%` 取余和 `^` 幂运算也有可能抛出 `ArithmeticException`(例如,当对负数进行取余或求幂时)。
* 多个异常类型可以组合捕获,如 `ArithmeticException | UnsupportedOperationException`。
* 保留了通用的 `Exception` 捕获作为后备选项,以处理未能预料的异常情况。
* `finally` 块确保了无论如何 `Scanner` 都会被关闭。
 */

import java.util.InputMismatchException;
import java.util.Scanner;

public class ExceptionCalculate {

    public static double calculate(double number1, double number2, String operation) {
        switch (operation) {
            case "+":
                return number1 + number2;
            case "-":
                return number1 - number2;
            case "*":
                return number1 * number2;
            case "/":
                if (number2 == 0) {
                    throw new ArithmeticException("除数不能为0。");
                }
                return number1 / number2;
            case "%":
                return number1 % number2;
            case "^":
                return Math.pow(number1, number2);
            default:
                throw new UnsupportedOperationException("不支持的操作: " + operation);
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        try {
            System.out.println("请输入第一个数字:");
            double number1 = scanner.nextDouble();
            System.out.println("请输入第二个数字:");
            double number2 = scanner.nextDouble();

            System.out.println("请选择操作 (+, -, *, /, %, ^):");
            String operation = scanner.next();

            double result = calculate(number1, number2, operation);
            System.out.println("结果: " + result);
        } catch (InputMismatchException e) {
            System.out.println("错误: 输入不是有效的数字。");
        } catch (ArithmeticException | UnsupportedOperationException e) {
            System.out.println("错误: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("未知错误: " + e.getMessage());
        } finally {
            scanner.close();
            System.out.println("计算器已关闭。");
        }
    }
}

Log4j 了解即可

Log4j是一个组件化设计的日志系统,它的架构大致如下:

log.info("User signed in.");
 │
 │   ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
 ├──>│ Appender │───>│  Filter  │───>│  Layout  │───>│ Console  │
 │   └──────────┘    └──────────┘    └──────────┘    └──────────┘
 │
 │   ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
 ├──>│ Appender │───>│  Filter  │───>│  Layout  │───>│   File   │
 │   └──────────┘    └──────────┘    └──────────┘    └──────────┘
 │
 │   ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
 └──>│ Appender │───>│  Filter  │───>│  Layout  │───>│  Socket  │
     └──────────┘    └──────────┘    └──────────┘    └──────────┘

Log4j是一个流行的Java日志框架,由Apache软件基金会开发。它用于记录应用程序的运行信息。Log4j允许开发人员控制日志信息的输出目的地(如控制台、文件、GUI组件等),以及输出格式,并且可以根据运行时信息动态地改变这些配置。Log4j使用简单而强大的配置语言,能够让开发人员启用或禁用特定的日志记录语句,控制每个日志记录语句的粒度,并通过过滤器对记录信息进行细粒度的控制。

Log4j的主要组件包括:

  • Logger:负责捕获日志信息。它是与日志记录调用交互的主要对象。
  • Appender:定义了日志信息的输出目的地,例如控制台、文件、数据库等。
  • Layout:负责格式化日志信息的输出格式。
  • Level:定义了日志信息的级别,例如DEBUG、INFO、WARN、ERROR、FATAL等。

Log4j的设计基于以下三个简单的概念:日志记录器(logger)、日志级别(level)、日志输出器(appender)。通过这种方式,Log4j提供了灵活的日志管理策略,允许开发者在运行时调整日志输出和级别,而无需修改应用程序代码。

例如,如果一个开发者在开发过程中需要调试信息,他可以将日志级别设置为DEBUG。一旦问题解决,可以修改配置文件将日志级别改回为INFO或者WARN,降低日志的冗余度,并且这些调整无需重启应用程序。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值