java中受检异常有哪些
在 Java 中,受检异常 (Checked Exception) 是指所有继承自 java.lang.Exception
但不继承自 java.lang.RuntimeException
的异常类及其子类。
编译器会强制要求你在代码中对受检异常进行处理(try-catch
)或在方法签名中声明抛出(throws
)。
以下是一些 Java 标准库中最常见、最重要的受检异常及其典型应用场景:
📌 核心受检异常列表:
-
java.io.IOException
(及其众多子类) - I/O 错误的核心代表:-
FileNotFoundException
: 尝试打开的文件不存在或不可访问。 -
EOFException
: 在输入过程中意外到达文件或流末尾。 -
SocketException
: 网络通信(TCP Socket)相关的底层错误。 -
MalformedURLException
: URL 字符串格式不正确。 -
UnsupportedEncodingException
: 字符编码名称不被支持(如getBytes("INVALID_ENCODING")
)。 -
CharConversionException
(及子类):字符转换错误 (属于java.io
或javax.xml.transform
等)。 -
使用场景: 文件操作(读/写)、网络通信 (Socket, URL)、流操作(
InputStream
,OutputStream
,Reader
,Writer
)。
-
-
java.sql.SQLException
(及其子类) - 数据库交互错误:-
SQLTimeoutException
: SQL 查询执行超时。 -
SQLSyntaxErrorException
: SQL 语句语法错误。 -
BatchUpdateException
: 批量 SQL 命令执行出错。 -
使用场景: JDBC 操作(连接数据库、执行 SQL 语句、处理结果集)。
-
-
java.text.ParseException
- 数据格式解析错误:-
使用场景: 使用
SimpleDateFormat
解析日期字符串 (parse()
方法),自定义格式解析时格式不匹配。
-
-
javax.naming.NamingException
(及其子类) - JNDI 操作错误:-
NameNotFoundException
: 在命名服务(如 LDAP 目录、Java EE 服务器的 JNDI 资源)中找不到名称。 -
使用场景: 访问企业级应用中的 JNDI 资源(数据库连接池、消息队列、EJB 等)。
-
-
java.net.URISyntaxException
- URI 格式错误:-
使用场景: 创建
java.net.URI
对象时,提供的 URI 字符串格式无效。
-
-
java.lang.ClassNotFoundException
- 类未找到:-
使用场景:
-
使用
Class.forName()
动态加载类。 -
使用
ClassLoader.loadClass()
/ClassLoader.findClass()
。 -
当依赖的类(编译时存在)在运行时类路径(Classpath)中缺失时。
-
特殊点: 虽然涉及类加载(本质是 JVM 机制),但因其代表资源(类)未找到的环境错误,故定为受检异常。
-
-
-
java.lang.NoSuchMethodException
- 反射方法未找到:-
使用场景: 通过反射获取方法时找不到匹配的方法(方法名或参数列表错误),使用
Class.getMethod()
,Class.getDeclaredMethod()
。
-
-
java.lang.NoSuchFieldException
- 反射字段未找到:-
使用场景: 通过反射获取字段时找不到匹配的字段,使用
Class.getField()
,Class.getDeclaredField()
。
-
-
java.lang.IllegalAccessException
- 非法访问:-
使用场景: 反射时尝试访问私有(private)、受保护(protected)、包私有(default)的构造方法、字段或方法。
-
-
java.lang.InstantiationException
- 实例化失败:-
使用场景: 通过反射创建实例失败:
-
类没有合适的无参构造函数。
-
类是接口或抽象类。
-
使用
Class.newInstance()
(Deprecated in JDK9) 或Constructor.newInstance()
。
-
-
-
java.lang.reflect.InvocationTargetException
- 调用目标异常:-
使用场景: 反射中调用方法(
Method.invoke()
)或构造函数(Constructor.newInstance()
)时,目标方法/构造方法内部自身抛出了一个异常。这个受检异常包装了实际的底层异常(通过getTargetException()
获取)。
-
-
java.io.ObjectStreamException
(及其子类) - 对象序列化/反序列化错误:-
InvalidClassException
: 序列化使用的类描述与本地类不兼容(类结构已改变)。 -
NotSerializableException
: 尝试序列化一个没有实现Serializable
接口的对象。 -
OptionalDataException
: 反序列化时,遇到非预期的基本类型数据或对象结束标记。 -
使用场景: 使用
ObjectInputStream
或ObjectOutputStream
进行对象序列化和反序列化。
-
-
java.time.format.DateTimeParseException
(Java 8+) - 日期时间解析错误:-
使用场景: 使用
DateTimeFormatter
解析日期时间字符串 (parse()
方法)。注意:它直接继承自RuntimeException
吗?不是!它继承自DateTimeException
->RuntimeException
? 这里要澄清:DateTimeParseException
是RuntimeException
!-
澄清:
DateTimeParseException
确实继承自java.time.DateTimeException
,而DateTimeException
继承自RuntimeException
。所以DateTimeParseException
是 运行时异常 (Unchecked Exception)。这反映了其更倾向于指示编程错误(错误格式的字符串)或数据错误,而非外部资源或环境问题。
-
-
因此,
DateTimeParseException
不属于受检异常。之前提及它是一个常见的例子。感谢指正!
-
📌 关键总结:受检异常特征
-
继承关系:
Exception
->Checked Exception
(排除所有RuntimeException
及子类)。 -
编译器强制处理: 必须使用
try-catch
捕获或在方法签名中用throws
声明。 -
代表意义: 指示程序外部环境可能出错或资源可能不可用的情况。这些通常是程序员可以预见并有责任妥善处理的“非逻辑性”错误:
-
文件/网络资源/数据库等 I/O 错误
-
关键依赖(如类文件、JAR)缺失
-
外部服务失败或通信错误
-
配置错误(如不支持的编码格式、无效的 URL/URI)
-
用户输入的数据格式不合法(需要解析时)
-
反射访问受限资源导致的访问问题
-
-
目标: 通过强制处理,提高程序的健壮性和错误恢复能力。
📌 如何区别于运行时异常 (RuntimeException / Unchecked)?
-
运行时异常: 继承自
RuntimeException
(ClassCastException
,NullPointerException
,IndexOutOfBoundsException
,NumberFormatException
,IllegalArgumentException
)。编译器不强制处理。它们通常反映程序员编码中的逻辑错误或无效假设(如参数不合法、空指针、类型转换错误、数组越界、错误的数值格式),这类错误应在开发和测试阶段通过严谨的代码避免,而不是依赖在运行时捕获。
当你看到编译器报错提示类似 Unhandled exception type XYZException
时,这就是告诉你 XYZException
是一个受检异常,你需要按照 Java 的规则去处理它(try-catch
或 throws
)。