1. Throwable
Throwable: 所有异常和错误的根类。实现 Throwable 或其子类的对象才能被 throw 或 catch。
Error: 表示严重的系统级问题,通常不应该被捕获或处理,程序通常无法从中恢复。
Exception: 表示程序可以处理的问题。分为 运行时异常、 受检异常 两类。
运行时异常: 不强制要求 try-catch 处理。通常是程序逻辑错误。
受检异常: 编译时必须处理(try-catch 或 throws)。表示外部环境问题或可恢复的异常。
java.lang.Throwable :
├── java.lang.Error : 错误
│ ├── java.lang.VirtualMachineError : JVM 出现严重问题
│ │ ├── java.lang.OutOfMemoryError : 内存不足
│ │ ├── java.lang.StackOverflowError : 栈溢出
│ │ ├── java.lang.UnknownError : 未知的虚拟机错误
│ │ └── ...
│ ├── java.lang.LinkageError : 类依赖问题
│ │ ├── java.lang.ClassFormatError : 类文件格式错误
│ │ ├── java.lang.NoClassDefFoundError : 类在编译时存在,运行时找不到
│ │ ├── java.lang.UnsupportedClassVersionError : JVM 版本不支持该类版本
│ │ └── ...
│ ├── java.lang.ThreadDeath : 线程被终止(调用 thread.stop())
│ ├── java.lang.ExceptionInInitializerError : 静态初始化出错
│ └── ...
│
└── java.lang.Exception : 异常├── java.lang.RuntimeException : 运行时异常│ ├── java.lang.ArithmeticException : 算术异常(除0)│ ├── java.lang.ArrayStoreException : 数组存储类型不匹配│ ├── java.lang.ClassCastException : 类型转换异常│ ├── java.lang.IllegalArgumentException : 非法参数│ │ ├── java.lang.NumberFormatException : 字符串转数字失败│ │ └── ...│ ├── java.lang.IndexOutOfBoundsException : 索引越界│ │ ├── java.lang.ArrayIndexOutOfBoundsException : 数组索引越界│ │ └── java.lang.StringIndexOutOfBoundsException : 字符串索引越界(charAt, substring, indexOf, codePointAt)│ ├── java.lang.NullPointerException : 访问孔对象的属性或方法│ ├── java.lang.SecurityException : 安全限制阻止操作│ └── ...│├── java.io.IOException : I/O异常(受检异常)│ ├── java.io.FileNotFoundException : 文件不存在│ ├── java.io.InterruptedIOException : I/O被中断│ └── ...│├── java.lang.ClassNotFoundException : 找不到类├── java.lang.CloneNotSupportedException : 不允许克隆├── java.lang.IllegalAccessException : 访问权限不足├── java.lang.InstantiationException : 无法实例化类├── java.lang.NoSuchFieldException : 字段不存在├── java.lang.NoSuchMethodException : 方法不存在├── java.sql.SQLException : 数据库操作失败└── 自定义异常(如:MyException)
2. 自定义异常
可以根据需要定义自己的异常类,通常继承 Exception(受检)或 RuntimeException(非受检)。
// 自定义受检异常
public class MyException extends Exception {public MyException(String message) {super(message);}
}// 自定义运行时异常
public class MyRuntimeException extends RuntimeException {public MyRuntimeException(String message) {super(message);}
}
3. ArithmeticException 算术异常
数学运算中出现异常情况 时抛出,例如 整数除以零 或 取模运算时除数为零。
浮点数除0不会抛异常,返回Infinity。
/*** ArithmeticException: 算术异常*/
public static void test_ArithmeticException() {try {// 除 0System.out.println(10/0);} catch (ArithmeticException e) {// java.lang.ArithmeticException: / by zeroe.printStackTrace();}// 浮点数除0不会抛异常!!!double result = 10.0 / 0.0;System.out.println(result); // Infinity
}
4. ArrayStoreException 数组存储类型不匹配
将一个类型不兼容的对象插入到数组中时,在运行时抛出 ArrayStoreException。
/*** ArrayStoreException: 数组存储类型不匹配*/
public static void test_ArrayStoreException() {try {Object[] strings = new String[3];strings[0] = "hello";// 尝试将一个非 String 类型的元素放入数组strings[1] = 123;} catch (ArrayStoreException e) {// java.lang.ArrayStoreException: java.lang.Integere.printStackTrace();}
}
5. ClassCastException 类型转换异常
将一个对象转换为它不兼容的类型时,Java 就会在运行时抛出 ClassCastException。
/*** ClassCastException: 类型转换异常*/
public static void test_ClassCastException() {try {Object obj = new Integer(10);// 尝试向下转型为不兼容的类型String str = (String) obj;System.out.println(str);} catch (ClassCastException e) {// java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Stringe.printStackTrace();}
}
6. IllegalArgumentException 类型转换异常
在 方法接收到非法或不合适的参数值 时抛出,表示传入的参数不符合方法的预期要求。
/*** IllegalArgumentException: 非法参数*/
public static void test_IllegalArgumentException(int i) {try {if(i > 5) {// 手动抛出throw new IllegalArgumentException("传入参数值不能超过5");}} catch (IllegalArgumentException e) {// java.lang.IllegalArgumentException: 传入参数值不能超过5e.printStackTrace();}
}
7. NumberFormatException 字符串转数字失败
将字符串转换为数值类型(如 int、double 等)失败时抛出。
/*** NumberFormatException: 字符串转数字失败*/
public static void test_NumberFormatException() {try {String str = "123abc";Integer.parseInt(str);} catch (NumberFormatException e) {// java.lang.NumberFormatException: For input string: "123abc"e.printStackTrace();}
}
8. ArrayIndexOutOfBoundsException 数组越界异常
访问数组元素时使用了非法索引(负数或大于等于数组长度的值) 时抛出。
/*** ArrayIndexOutOfBoundsException: 数组越界异常*/
public static void test_ArrayIndexOutOfBoundsException() {try {Integer[] integers = new Integer[5];integers[5] = 0;} catch (ArrayIndexOutOfBoundsException e) {// java.lang.ArrayIndexOutOfBoundsException: 5e.printStackTrace();}
}
9. StringIndexOutOfBoundsException 字符串越界异常
访问字符串中字符时使用了非法索引(负数或大于等于字符串长度) 时抛出。
/*** StringIndexOutOfBoundsException: 字符串越界异常*/
public static void test_StringIndexOutOfBoundsException() {try {String s = "12345";s.charAt(5);} catch (StringIndexOutOfBoundsException e) {// java.lang.StringIndexOutOfBoundsException: String index out of range: 5e.printStackTrace();}
}
10. NullPointerException 空指针异常
尝试在 一个为 null 的对象引用上调用方法或访问属性 时,就会抛出 NullPointerException。
/*** NullPointerException: 空指针异常*/
public static void test_NullPointerException() {try {String s = null;s.length();} catch (NullPointerException e) {// java.lang.NullPointerExceptione.printStackTrace();}
}
11. SecurityException 安全限制阻止操作
程序试图执行某些受安全管理器限制的操作时抛出。
/*** SecurityException: 安全限制阻止操作*/
public static void test_SecurityException() {// 设置一个安全管理器System.setSecurityManager(new SecurityManager());try {String property = System.getProperty("user.name");System.out.println(property);} catch (SecurityException e) {// java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.name" "read")e.printStackTrace();}
}
12. IOException IO异常(受检异常)
在进行文件读写、网络通信、流操作等 I/O 操作时抛出。
- FileNotFoundException: 试图打开一个不存在的文件 或 路径无效 时抛出的异常。
- InterruptedIOException: I/O 操作被中断(线程被中断)时抛出。
/*** IOException: IO异常(受检异常)*/
public static void test_IOException() {// 设置一个安全管理器try {FileReader fileReader = new FileReader("file.txt");int read = fileReader.read();while(read != -1) {System.out.println((char)read);read = fileReader.read();}fileReader.close();} catch (IOException e) {// FileNotFoundException 文件不存在异常// java.io.FileNotFoundException: file.txt (系统找不到指定的文件。)e.printStackTrace();}
}/*** InterruptedIOException: I/O 操作中断*/
public static void test_InterruptedIOException() {Thread ioThread = new Thread(() -> {try (InputStream is = new PipedInputStream()) {System.out.println("开始读取...");is.read(); // 阻塞等待输入} catch (InterruptedIOException e) {System.out.println("I/O 操作被中断: " + e.getMessage());} catch (IOException e) {// java.io.IOException: Pipe not connectede.printStackTrace();}});ioThread.start();// 中断线程ioThread.interrupt();
}
13. ClassNotFoundException 找不到类(受检异常)
该异常通常在 使用类名字符串动态加载类(如通过 Class.forName())时抛出。
/*** ClassNotFoundException: 找不到类*/
public static void test_ClassNotFoundException() {try {// 尝试加载一个不存在的类Class<?> clazz = Class.forName("com.example.NonExistentClass");} catch (ClassNotFoundException e) {// java.lang.ClassNotFoundException: com.example.NonExistentClasse.printStackTrace();}
}
14. CloneNotSupportedException 不允许克隆(受检异常)
该异常通常在调用 Object.clone() 方法时,如果对象的类 没有实现 Cloneable 接口,就会抛出。
// class Person implements Cloneable
// 没有实现 Cloneable 是不允许调用 clone 进行克隆的
static class Person {String name;public Person(String name) {this.name = name;}@Overridepublic Person clone() throws CloneNotSupportedException {return (Person) super.clone();}
}/*** CloneNotSupportedException : 不允许克隆*/
public static void test_CloneNotSupportedException() {Person p1 = new Person("Alice");try {Person p2 = (Person) p1.clone();} catch (CloneNotSupportedException e) {// java.lang.CloneNotSupportedException: com.lkm.test.Test_Throwable$Persone.printStackTrace();}
}
15. IllegalAccessException 访问权限不足(受检异常)
在运行时通过反射机制尝试访问类、方法、字段等成员时,如果该成员的访问权限不足(例如是 private),并且没有通过 setAccessible(true) 显式开启访问权限,就会抛出该异常。
/*** IllegalAccessException : 访问权限不足*/
public static void test_IllegalAccessException() {class Person {private String name = "Alice";}try {Person person = new Person();Field field = person.getClass().getDeclaredField("name");// 尝试获取私有字段的值,但未设置可访问System.out.println(field.get(person)); // 抛出 IllegalAccessException} catch (NoSuchFieldException | IllegalAccessException e) {// java.lang.IllegalAccessException: Class com.lkm.test.Test_Throwable can not access a member of class com.lkm.test.Test_Throwable$1Person with modifiers "private"e.printStackTrace();}
}
16. InstantiationException 无法实例化类(受检异常)
通常在使用 反射机制 创建类的实例时抛出,尤其是在调用 Class.newInstance() 或 Constructor.newInstance() 时,如果目标类无法被实例化,就会抛出这个异常。
- 类是抽象类(abstract):抽象类不能直接实例化
- 类是接口(interface):接口也不能直接实例化
- 没有无参构造函数:如果类没有默认构造函数(0个参数),而你使用 Class.newInstance()
- 构造函数抛出异常:构造函数执行过程中抛出了异常,也会导致此异常
17. NoSuchFieldException 字段不存在(受检异常)
通常在使用 反射(Reflection) 机制访问类的字段(成员变量)时抛出,表示你尝试访问的字段在目标类中 不存在。
/*** NoSuchFieldException : 字段不存在*/
public static void test_NoSuchFieldException() {class Person {private String name;public int age;}try {Class<?> clazz = Person.class;Field field = clazz.getField("gender"); // 尝试访问不存在的 public 字段} catch (NoSuchFieldException e) {// java.lang.NoSuchFieldException: gendere.printStackTrace();}
}
18. NoSuchMethodException 方法不存在(受检异常)
通常在使用 反射(Reflection) 机制访问类的方法时抛出,表示你尝试调用的方法在目标类中 不存在,或者参数类型不匹配。
/*** NoSuchMethodException : 方法不存在*/
public static void test_NoSuchMethodException() {class Person {public void sayHello() {System.out.println("Hello");}}try {Class<?> clazz = Person.class;Method method = clazz.getMethod("sayGoodbye"); // 方法不存在} catch (NoSuchMethodException e) {// java.lang.NoSuchMethodException: com.lkm.test.Test_Throwable$1Person.sayGoodbye()e.printStackTrace();}
}
19. SQLException 数据库操作失败(受检异常)
用于处理 数据库访问错误 的一个 受检异常(Checked Exception),它通常在使用 JDBC(Java Database Connectivity)与数据库交互时抛出。当执行 SQL 语句、连接数据库、处理结果集等操作失败时,JDBC 驱动会抛出 SQLException。
- 数据库连接失败:错误的 URL、用户名、密码
- SQL 语法错误:SQL 语句拼写错误、表名不存在
- 数据库服务未启动:数据库服务器宕机或无法访问
- 权限不足:当前用户没有执行该操作的权限
- 网络问题:数据库服务器无法连接(超时)
- 数据类型不匹配:插入或查询时类型不匹配
- 主键冲突:插入重复主键
- 空指针访问:使用已关闭的 Connection、Statement、ResultSet
/*** SQLException : 数据库操作失败*/
public static void test_SQLException() {String url = "jdbc:mysql://localhost:3306/nonexistentdb"; // 错误的数据库名String user = "root";String password = "wrongpassword"; // 错误密码try {Connection conn = DriverManager.getConnection(url, user, password);} catch (SQLException e) {System.out.println("SQLException: " + e.getMessage()); // SQLException: No suitable driver found for jdbc:mysql://localhost:3306/nonexistentdbSystem.out.println("SQLState: " + e.getSQLState()); // SQLState: 08001System.out.println("Error Code: " + e.getErrorCode()); // Error Code: 0// java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/nonexistentdbe.printStackTrace();}
}