异常
约 1433 字大约 5 分钟
2025-01-15
1.定义
错误(Error)与异常(Exception)的区别:
- Error:代表 JVM 自身的异常,无法通过程序来修正,最可靠的方式就是尽可能快地停止 JVM 的运行,常见的 Error 有:
java.lang.VirtualMachineError
(Java虚拟机运行错误):当 Java虚拟机崩溃或用尽了它继续操作所需的资源时,抛出该错误java.lang.StackOverflowError
(栈溢出错误):当应用程序递归太深而发生堆栈溢出时,抛出该错误java.lang.OutOfMemoryError
(内存溢出):内存溢出或没有可用的内存提供给垃圾回收器时,产生这个错误
- Exception:代表程序运行中发生了意料之外的事情,这些意外的事情可以被 Java 异常处理机制处理。
Exception,指程序本身可以处理的错误(可以向上抛出或者捕获处理)
2.异常类继承层次
2.1 Thowable
- 异常是对象,异常封装成类Exception,所有的异常都直接或间接继承自Throwable类。
- Throwable 类有两个直接的子类,Error和Exception。
- 可以通过继承Exception或Exception的子类来创建自己的异常类。
- Exception是程序可以恢复的异常。如除零异常、空指针访问、网络连接中断、读取不存在的文件等。
- Exception类分为受检查异常和运行时异常
- 受检查异常(必检异常):是除RuntimeException以外的异常,特点是编译器会强制程序员检查并通过try-catch块处理它们,或在方法头进行声明。如处理数据库异常的SQLException,处理读写异常的IOException
- 运行时异常(免检异常):是继承RuntimeExceptionl类的直接或间接类。编译器不检查这类异常是否进行了处理,也就是对于这类异常不捕获也不抛出,程序也可以编译通过。一旦运行时异常时就会导致程序的终止。如访问一个数组的越界元素,会抛出一个IndexOutofBoundsException异常。
2.2 常见异常
- 检查性异常:
- IOException:IO 异常
- FileNotFoundException:文件找不到异常
- ClassNotFoundExcetption:类找不到异常
- 运行时异常:
- NullPointerException:空指针异常
- IndexOutOfBoundsException:数组下标越界异常
- ClassCastException:类型转换异常
3.异常的处理模型
Java的异常处理模型基于三种操作:
- 声明一个异常
- 抛出一个异常或者捕获一个异常。
3.1 声明并抛出异常
3.1.1 throws 声明异常
throws 通常在方法首部的声明后抛出异常,抛出的是可能发生的异常。当该方法被调用的时候必须捕获,或者也可以再次抛出异常,最终由 Java 虚拟机处理。
用来声明一个方法可能产生的所有异常(用,分隔), 不做任何处理而是将异常往上传,谁调用我我就抛给谁。
举例:
class MyAnimation{
public Image loadImage(String s) throws IOException{
...
}
}
3.1.2 throw抛出异常
throw 关键字通常用在方法体中,并且抛出一个异常对象。执行 throw 则一定抛出了某种异常,只能抛出一个异常对象
举例:
String readData(Scanner in)throws EOFException{
while(...){
if(!in.hasNext())//遇到EOFException异常
if(n<len){
throw new EOFException();
}
}
}
3.1.3 小结
- throw抛出一个异常对象时需要由函数的上层调用处理这个异常,此时,可以通过 try-catch(finally)代码块,也可以通过throws进行抛出。(一定要处理)
- throws抛出一个可能的异常时可以不对此异常进行处理。
3.2 捕获异常
3.2.1 try-catch-finally语句
try{
//需要被检测的异常代码
}catch(Exception e){
//异常处理,即处理异常的代码(打印异常信息并处理)
}finally{
//一定会被执行的代码(通常可以进行资源的清除工作)
}
3.2.2 try-catch语句
try{
//需要被检测的异常代码
}catch(Exception e){
//异常处理,即处理异常的代码(打印异常信息并处理)
}
3.2.3 try-finally语句
try{
//需要被检测的异常代码
}finally{
//一定会被执行的代码(通常可以进行资源的清除工作)
}
3.2.4 多catch语句
try{
//需要被检测的异常代码
}catch(Exception e1){
//异常处理,即处理异常的代码(打印异常信息并处理)
}catch(IOException e2){
//异常处理,即处理异常的代码(打印异常信息并处理)
} //可以通过catch处理多个异常。
3.3 举例
public class TestException {
//测试0
boolean testEx() throws Exception{
boolean res = true;
try{
res = testEx1();//执行
}catch (Exception e){
System.out.println("测试0,捕获异常");
res = false;
throw e;
}finally{
System.out.println("测试0, finally 最终返回的值 =" + res);
return res;
}
}
//测试1
boolean testEx1() throws Exception{
boolean res= true;
try{
res = testEx2();
if (!res){
return false;
}
return res;
}catch (Exception e){
System.out.println("测试1, catch捕获");
res = false;
throw e;
}finally{
System.out.println("测试1, finally最终返回值 =" + res);
return res;
}
}
//测试2
boolean testEx2() throws Exception{
boolean res = true;
try{
int b = 2;
int c;
for (int i = 2; i >= 0; i--){
c = b / i;
System.out.println("c="+c+"\ti=" + i);
}
return true;
}catch (Exception e){
System.out.println("测试2, catch捕获");
res = false;
throw e;
}finally{
System.out.println("测试2, finally最终值 =" + res);
return res;
}
}
}//借鉴Angel_Kitty的例子
4.自定义异常
4.1 自定义异常类
class CustomException extends Exception {
private String customMessage;
public CustomException(String message) {
super(message);
this.customMessage = message;
}
public String getCustomMessage() {
return customMessage;
}
}
4.2 测试类—>并抛出自己的异常
class Example {
public static void main(String[] args) {
try {
// 模拟条件触发自定义异常抛出
int age = -1;
if (age < 0) {
throw new CustomException("年龄不能为负数");
}
} catch (CustomException e) {
System.out.println("捕获到自定义异常:" + e.getCustomMessage());
}
}
}