Java 异常详细介绍

Java 的异常(Exception)是指程序在运行过程中出现的不正常情况,通常是程序无法预料的错误。异常发生时,程序的执行会中断。Java 提供了强大的异常处理机制,以便开发者能够捕获和处理这些异常,保证程序的健壮性和稳定性。

异常的处理机制使得 Java 程序能够在出现问题时,避免整个应用程序崩溃,而是能够优雅地处理错误,或者向用户报告有用的错误信息。

1. 异常分类

Java 中的异常按照是否需要强制处理、异常发生的层次、是否可以恢复等因素,分为以下几类:

1.1 检查异常(Checked Exception)

检查异常是 Java 编译器强制要求处理的异常。如果代码中抛出了检查异常,必须显式地捕获该异常或通过 throws 关键字声明抛出。

  • 例如:IOExceptionSQLExceptionClassNotFoundException 等。
  • 检查异常通常是由外部因素引起的,比如文件未找到、数据库连接失败等。

示例:

java

import java.io.*;

public class CheckedExceptionExample {
    public static void main(String[] args) {
        try {
            // FileInputStream 是一个会抛出检查异常的操作
            FileInputStream file = new FileInputStream("file.txt");
            int data = file.read();
            file.close();
        } catch (IOException e) {
            // 必须捕获并处理检查异常
            System.out.println("An error occurred while reading the file: " + e.getMessage());
        }
    }
}

1.2 运行时异常(Unchecked Exception)

运行时异常是 Java 中的 非检查异常,也叫 运行时异常,它是 RuntimeException 类的子类。运行时异常通常是由程序逻辑错误引起的,编译器不会强制要求处理这些异常。

  • 例如:NullPointerExceptionArrayIndexOutOfBoundsExceptionArithmeticException 等。
  • 运行时异常通常表示程序本身的错误,需要通过代码修改来修复。

示例:

java

public class UncheckedExceptionExample {
    public static void main(String[] args) {
        try {
            // 可能会引发运行时异常:除数为零
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            // 捕获并处理运行时异常
            System.out.println("Cannot divide by zero: " + e.getMessage());
        }
    }
}

1.3 错误(Error)

错误表示系统层面的问题,通常是不可恢复的。Error 类及其子类通常不应由程序进行捕获和处理。常见的错误包括 OutOfMemoryErrorStackOverflowError 等。

  • 这些错误通常是由于 JVM 本身的资源耗尽或异常状态引起的。
  • 一般情况下,程序应该避免发生这些错误,但如果发生了,通常无法恢复。

示例:

java

public class ErrorExample {
    public static void main(String[] args) {
        try {
            // 触发 StackOverflowError,递归调用
            recursiveMethod();
        } catch (StackOverflowError e) {
            System.out.println("StackOverflowError occurred: " + e.getMessage());
        }
    }

    public static void recursiveMethod() {
        recursiveMethod();
    }
}

2. 异常处理机制

Java 提供了异常处理机制,让程序能够优雅地处理异常,而不是直接终止。

2.1 try-catch-finally 语句

Java 的异常处理通过 try-catch-finally 语句来实现。try 块用于包含可能发生异常的代码;catch 块用于捕获异常并处理;finally 块包含无论是否发生异常都需要执行的代码。

java

try {
    // 可能发生异常的代码
} catch (ExceptionType1 e1) {
    // 处理 ExceptionType1 异常的代码
} catch (ExceptionType2 e2) {
    // 处理 ExceptionType2 异常的代码
} finally {
    // 不管是否发生异常,都会执行的代码(可选)
}

2.2 try-catch-finally 代码示例

java

public class TryCatchFinallyExample {
    public static void main(String[] args) {
        try {
            // 可能发生异常的代码
            int result = 10 / 0;  // ArithmeticException
        } catch (ArithmeticException e) {
            // 捕获并处理异常
            System.out.println("Error: " + e.getMessage());
        } finally {
            // 无论是否发生异常,都会执行
            System.out.println("This block always executes.");
        }
    }
}

输出:

vbnet

Error: / by zero
This block always executes.

2.3 多重捕获(Multi-catch)

Java 7 及以上版本支持多重捕获,即在一个 catch 块中捕获多种类型的异常,简化代码结构。

java

public class MultiCatchExample {
    public static void main(String[] args) {
        try {
            String str = null;
            str.length();  // 会抛出 NullPointerException
        } catch (NullPointerException | ArithmeticException e) {
            // 捕获多种异常类型
            System.out.println("An exception occurred: " + e.getMessage());
        }
    }
}

2.4 throw 和 throws 关键字

  • throw 关键字:用于显式抛出一个异常对象。
  • throws 关键字:用于声明方法可能抛出的异常类型,提醒调用者处理这些异常。
throw 示例
java

public class ThrowExceptionExample {
    public static void main(String[] args) {
        try {
            throw new IllegalArgumentException("Invalid argument");
        } catch (IllegalArgumentException e) {
            System.out.println("Caught exception: " + e.getMessage());
        }
    }
}

throws 示例
java

import java.io.*;

public class ThrowsExample {
    public static void main(String[] args) {
        try {
            readFile("file.txt");
        } catch (IOException e) {
            System.out.println("An error occurred while reading the file.");
        }
    }

    // 使用 throws 声明方法可能抛出的异常
    public static void readFile(String fileName) throws IOException {
        FileInputStream file = new FileInputStream(fileName);
        int data = file.read();
        file.close();
    }
}

3. 常见异常类型

3.1 NullPointerException

NullPointerException 是当程序试图访问或操作 null 引用时抛出的异常。

示例:

java

public class NullPointerExceptionExample {
    public static void main(String[] args) {
        String str = null;
        System.out.println(str.length());  // 会抛出 NullPointerException
    }
}

3.2 ArrayIndexOutOfBoundsException

当程序试图访问数组中不存在的索引时,会抛出 ArrayIndexOutOfBoundsException

示例:

java

public class ArrayIndexOutOfBoundsExceptionExample {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println(arr[5]);  // 会抛出 ArrayIndexOutOfBoundsException
    }
}

3.3 ArithmeticException

当程序出现数学运算错误时,会抛出 ArithmeticException,例如除以零。

示例:

java

public class ArithmeticExceptionExample {
    public static void main(String[] args) {
        int result = 10 / 0;  // 会抛出 ArithmeticException
    }
}

3.4 ClassNotFoundException

当程序试图加载一个不存在的类时,会抛出 ClassNotFoundException

示例:

java

public class ClassNotFoundExceptionExample {
    public static void main(String[] args) {
        try {
            Class.forName("NonExistentClass");  // 会抛出 ClassNotFoundException
        } catch (ClassNotFoundException e) {
            System.out.println("Class not found: " + e.getMessage());
        }
    }
}

3.5 IOException

IOException 是在输入/输出操作失败或中断时抛出的异常。

示例:

java

import java.io.*;

public class IOExceptionExample {
    public static void main(String[] args) {
        try {
            FileReader reader = new FileReader("nonexistentfile.txt");  // 会抛出 FileNotFoundException
        } catch (IOException e) {
            System.out.println("IOException occurred: " + e.getMessage());
        }
    }
}

4. 自定义异常

Java 允许开发者自定义异常。通常有两种方式:

  • 自定义检查异常:继承 Exception 类。
  • 自定义运行时异常:继承 RuntimeException 类。

4.1 自定义检查异常

java

class CustomCheckedException extends Exception {
    public CustomCheckedException(String message) {
        super(message);
    }
}

public class CustomCheckedExceptionExample {
    public static void main(String[] args) {
        try {
            throw new CustomCheckedException("This is a custom checked exception");
        } catch (CustomCheckedException e) {
            System.out.println(e.getMessage());
        }
    }
}

4.2 自定义运行时异常

java

class CustomUncheckedException extends RuntimeException {
    public CustomUncheckedException(String message) {
        super(message);
    }
}

public class CustomUncheckedExceptionExample {
    public static void main(String[] args) {
        try {
            throw new CustomUncheckedException("This is a custom unchecked exception");
        } catch (CustomUncheckedException e) {
            System.out.println(e.getMessage());
        }
    }
}

5. 总结

  1. 检查异常(Checked Exceptions):必须显式捕获或声明,例如 IOExceptionSQLException 等。
  2. 运行时异常(Unchecked Exceptions):不需要强制处理,通常由程序错误引起,例如 NullPointerExceptionArithmeticException 等。
  3. 错误(Errors):通常是 JVM 层面的问题,不应由应用程序捕获和处理,例如 OutOfMemoryErrorStackOverflowError 等。
  4. 异常处理机制:通过 try-catch-finally 语句处理异常。
  5. 自定义异常:可以根据需要自定义异常类,以满足业务需求。
Java碎碎念 文章被收录于专栏

来一杯咖啡,聊聊Java的碎碎念呀

全部评论

相关推荐

字节 测开 25*15
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
2024-12-30 00:28
字节跳动 算法 123 其他
点赞 评论 收藏
分享
评论
4
3
分享

创作者周榜

更多
牛客网
牛客企业服务