Java-EE-异常
在Java中,异常被组织成一个层次结构,所有异常类都是java.lang.Throwable
类的子类。Throwable
类有两个主要的子类:Error
和Exception
。
Error(错误)
Error:表示编译时和运行时系统错误,这些错误通常是不可恢复的,如虚拟机错误(VirtualMachineError
)、AssertionError
等。通常,程序不会尝试捕获这些错误。
Exception(异常)
Exception:表示程序运行时可能发生的异常情况,它是所有异常的超类。Exception
类进一步被分为两个子类:受检异常(Checked Exceptions)、非受检异常(Unchecked Exceptions)
受检异常(Checked Exceptions)
受检异常(Checked Exceptions)是Java异常体系中的一种,它们是Exception
类的子类,但不包括RuntimeException
及其子类。受检异常是程序在编译时必须处理的异常,这意味着当一个方法抛出受检异常时,方法的调用者必须采取一定的措施来处理这个异常,这些措施包括:
- 捕获异常:使用
try...catch
语句捕获异常,并进行相应的处理。 - 声明抛出:使用
throws
关键字在方法签名中声明该方法可能会抛出的异常,这样异常就可以被方法的调用者处理。
受检异常通常是可预见的,并且调用者有能力处理或者恢复的异常。以下是一些常见的受检异常的例子:
IOException
:当发生与输入输出操作相关的异常时,如文件不存在、网络连接失败等。SQLException
:与数据库操作相关的异常,如查询语法错误、数据库连接失败等。FileNotFoundException
:尝试打开一个不存在的文件时抛出。MalformedURLException
:尝试创建一个不合法的URL时抛出。
下面是一个处理受检异常的示例:
import java.io.*;
public class CheckedExceptionExample {
public static void main(String[] args) {
try {
readFromFile("example.txt");
} catch (IOException e) {
System.out.println("发生输入输出异常:" + e.getMessage());
// 可以在这里添加更多的异常处理逻辑
}
}
public static void readFromFile(String filename) throws IOException {
FileReader file = new FileReader(filename);
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
reader.close();
System.out.println(line);
}
}
在这个例子中,readFromFile
方法可能会抛出IOException
,这是一个受检异常。因此,该方法在其声明中使用throws
关键字声明了这一点。在main
方法中,调用readFromFile
方法的代码被包裹在try...catch
块中,以捕获并处理可能发生的IOException
。
受检异常的设计初衷是强制程序员处理程序中可能出现的错误情况,从而提高程序的健壮性。然而,它们也受到了一些批评,因为有时它们被认为是不必要的复杂,尤其是在那些异常处理逻辑简单或者调用者无法做任何有意义的事情来处理异常的情况下。因此,Java社区中对于是否过度使用受检异常存在一定的讨论。
非受检异常(Unchecked Exceptions)
非受检异常(Unchecked Exceptions)是Java中Exception
类的一个分支,包括RuntimeException
及其子类。与受检异常不同,非受检异常不需要在方法的签名中显式声明,也不需要调用者必须捕获处理。它们通常是由于程序错误导致的异常,比如空指针访问、数组下标越界等。
非受检异常通常被认为是“可控”的异常,因为它们是程序员在编写代码时应该避免的错误。以下是一些常见的非受检异常的例子:
-
RuntimeException
:运行时异常是最常见的非受检异常之一,它表示程序运行时可能出现的错误,如:NullPointerException
:尝试使用null
对象引用。IndexOutOfBoundsException
:数组或集合的索引越界。IllegalArgumentException
:方法接收到不合法或不适当的参数。
-
ArithmeticException
:算术异常,如除以零。 -
IllegalStateException
:非法状态异常,当对象处于一个不合法的状态时抛出。 -
ConcurrentModificationException
:并发修改异常,当集合被多个线程同时修改时抛出。 -
UnsupportedOperationException
:不支持的操作异常,当尝试执行不支持的操作时抛出。
下面是一个示例,展示如何在Java中处理非受检异常:
public class UncheckedExceptionExample {
public static void main(String[] args) {
try {
int number = 1 / 0; // 这将抛出ArithmeticException
} catch (ArithmeticException e) {
System.out.println("发生算术异常:" + e.getMessage());
// 可以在这里添加更多的异常处理逻辑
}
}
}
在这个例子中,尝试执行除以零的操作会抛出ArithmeticException
,这是一个非受检异常。虽然非受检异常不需要在方法签名中声明,但仍然可以使用try...catch
语句来捕获并处理它们。
非受检异常的设计初衷是让开发者能够更灵活地处理异常,并且避免过度使用异常声明,这可能会导致代码变得复杂和冗长。然而,这也意味着开发者需要更加小心,确保他们能够正确地处理程序中可能出现的错误情况。