Java-异常
# 异常框架
# Throwable
Throwable
是 Java 语言中所有错误(Error
)和异常(Exception
)的超类。在 Java 中只有 Throwable
类型的实例才可以被抛出(throw
)或者捕获(catch
),它是异常处理机制的基本组成类型。
# Error
Error
是 Throwable
的一个子类。Error
表示正常情况下,不大可能出现的严重问题。编译器不会检查 Error
。绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如 OutOfMemoryError 之类,都是 Error 的子类。
常见Error
:
AssertionError
- 断言错误。VirtualMachineError
- 虚拟机错误。UnsupportedClassVersionError
- Java 类版本错误。StackOverflowError
- 栈溢出错误。OutOfMemoryError
- 内存溢出错误。
# Exception
Exception
是 Throwable
的一个子类。Exception
表示合理的应用程序可能想要捕获的条件。Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。
常见Exception
:
ClassNotFoundException
- 应用程序试图加载类时,找不到相应的类,抛出该异常。CloneNotSupportedException
- 当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。IllegalAccessException
- 拒绝访问一个类的时候,抛出该异常。InstantiationException
- 当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。InterruptedException
- 一个线程被另一个线程中断,抛出该异常。NoSuchFieldException
- 请求的变量不存在。NoSuchMethodException
- 请求的方法不存在。
# RuntimeException
RuntimeException
是 Exception
的一个子类。RuntimeException
是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。
# 自定义异常
自定义一个异常类,只需要继承 Exception
或 RuntimeException
即可。
public class MyExceptionDemo {
public static void main(String[] args) {
throw new MyException("自定义异常");
}
static class MyException extends RuntimeException {
public MyException(String message) {
super(message);
}
}
}
# 抛出异常
如果想在程序中明确地抛出异常,需要用到 throw
和 throws
。
throw实例:
public class ThrowDemo {
public static void f() {
try {
throw new RuntimeException("抛出一个异常");
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
f();
}
};
throws示例
public class ThrowsDemo {
public static void f1() throws NoSuchMethodException, NoSuchFieldException {
Field field = Integer.class.getDeclaredField("digits");
if (field != null) {
System.out.println("反射获取 digits 方法成功");
}
Method method = String.class.getMethod("toString", int.class);
if (method != null) {
System.out.println("反射获取 toString 方法成功");
}
}
public static void f2() {
try {
// 调用 f1 处,如果不用 try catch ,编译时会报错
f1();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
f2();
}
};
throw 和 throws 的区别:
- throws 使用在函数上,throw 使用在函数内。
- throws 后面跟异常类,可以跟多个,用逗号区别;throw 后面跟的是异常对象。
# 捕获对象
使用 try 和 catch 关键字可以捕获异常。try catch 代码块放在异常可能发生的地方。
try {
// 可能会发生异常的代码块
} catch (Exception e1) {
// 捕获并处理try抛出的异常类型Exception
} catch (Exception2 e2) {
// 捕获并处理try抛出的异常类型Exception2
} finally {
// 无论是否发生异常,都将执行的代码块
}
try {
// 可能会发生异常的代码块
} catch (Exception | Exception2 e) {
// 捕获并处理try抛出的异常类型
} finally {
// 无论是否发生异常,都将执行的代码块
}
try
-try
语句用于监听。将要被监听的代码(可能抛出异常的代码)放在try
语句块之内,当try
语句块内发生异常时,异常就被抛出。catch
-catch
语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try
后面的catch
块就会被检查。finally
-finally
语句块总是会被执行,无论是否出现异常。try catch
语句后不一定非要finally
语句。finally
常用于这样的场景:由于finally
语句块总是会被执行,所以那些在try
代码块中打开的,并且必须回收的物理资源(如数据库连接、网络连接和文件),一般会放在finally
语句块中释放资源。
示例:
public class TryCatchFinallyDemo {
public static void main(String[] args) {
try {
// 此处产生了异常
int temp = 10 / 0;
System.out.println("两个数字相除的结果:" + temp);
System.out.println("----------------------------");
} catch (ArithmeticException e) {
System.out.println("出现异常了:" + e);
} finally {
System.out.println("不管是否出现异常,都执行此代码");
}
}
};
# 参考
上次更新: 2024/06/29, 15:13:44