day17 异常
异常体系

- 定义:Java 的异常体系提供了一种机制,使得程序可以在遇到错误或异常时进行相应的处理,保证程序的稳定性和可靠性。程序员可以通过 try-catch-finally 语句来捕获和处理异常,以及通过 throw 和 throws 语句来抛出异常和声明方法可能会抛出的异常。
- Error 是指在程序运行期间发生的不可恢复的系统错误。当程序出现 Error 时,通常无法处理,只能让程序终止运行。
- OutOfMemoryError: Java 堆空间溢出
- NoSuchMethodError: 未找到方法
- NoClassDefFoundError: 找不到类定义
- ExceptionInInitializerError: 静态初始化块引发的异常
- LinkageError: 连接错误。
- Exception 是指在程序运行期间发生的可恢复的异常,例如输入错误、网络连接中断等。Exception 包括两种类型:
- Checked Exception 在代码中需要进行异常处理,否则会编译错误。
- IOException: 输入/输出异常
- ClassNotFoundException: 找不到类异常
- SQLException: SQL 异常
- ParseException: 解析异常
- InterruptedException: 中断异常。
- Runtime Exception 通常是由于程序代码逻辑错误造成的,例如数组越界、空指针引用等。Runtime Exception 可以不进行异常处理,但如果不处理,程序会在运行时抛出异常并终止运行。
- NullPointerException: 空指针异常
- ArrayIndexOutOfBoundsException: 数组下标越界异常
- IllegalArgumentException: 非法参数异常
- ClassCastException: 类型转换异常
- ArithmeticException: 算术异常。
- Checked Exception 在代码中需要进行异常处理,否则会编译错误。
Exception
- 在 Java 中,可以在方法声明中使用 throws 关键字来声明该方法可能抛出的异常。但是,并不是所有情况下都需要使用 throws 关键字来声明异常。以下情况下可以省略 throws 关键字(但是在实际开发中建议尽可能使用 throws 关键字声明可能抛出的异常,以便提高代码的可读性和可维护性。):
- 方法声明的异常类型为 RuntimeException 或其子类,这些异常通常被称为非受检异常,不需要在方法声明中使用 throws 关键字声明。
- 方法不会抛出任何异常,或者方法中的异常已经被处理或转化为非受检异常,这种情况下也可以省略 throws 关键字。
- 方法重写父类方法时,可以不使用 throws 关键字声明与父类方法相同的异常,但是如果方法声明了父类方法没有声明的异常,则需要使用 throws 关键字声明这些异常。
- 接口方法不能声明任何异常,因此在实现接口方法时不需要使用 throws 关键字声明异常。
- 运行时异常通常是由程序逻辑错误引起的,例如空指针异常、数组越界异常等。这些异常通常发生在程序运行时,而不是在编译时。由于这些异常在程序运行时才会被抛出,因此在方法声明中使用 throws 关键字声明这些异常并不能提高代码的安全性,反而会增加代码的冗余性和复杂性。
package note;
/**
* @Description 异常的基本使用
* @Author Noby
* @Date 2023/3/18 17:44
*/public class ExceptionNote {
public static void main(String[] args) {
//region 对于直接发生在main中且没有try catch的处理,会直接交给将异常抛给jvm,jvm会终止程序。如果异常经过try catch,将会继续运行程序
// System.out.println(100 / 0);
//endregion //region ArithmeticException 数学运算异常
try {//如果程序发生异常且没有被处理,将会将异常抛给jvm,jvm会终止程序
System.out.println(500 / 0);
System.out.println("发生异常后,try中的异常代码后的代码不执行");
} catch (ArithmeticException e) {//当一个try catch中存在多个catch时,执行其中一个catch后其他catch就不会继续执行
//catch中写出处理异常的方式
e.printStackTrace();//printStacktrace() 将异常信息打印出来
} catch (Exception e) {//多个catch捕获多个异常,且子类异常在前,可以捕获Exception及其子类的异常
System.out.println("这是一个Exception异常");
} finally {
System.out.println("finally中的代码不管异常是否发生都要执行的");
}
//endregion
//region NullPointerException 空指针异常 ArrayIndexOutOfBoundsException 越界异常
int[] arr = {1, 2, 3};
try {
method(arr, 3);
} catch (NullPointerException | ArrayIndexOutOfBoundsException ex) {
ex.printStackTrace();//处理空指针异常和越界异常的方式,打印
}
//endregion
//region ClassCastException 类型转换异常
try {
A b = new B();
B b1 = (B) b;
C b2 = (C) b;//ClassCastException 类型转换异常 b为B类型不能强转为C
} catch (ClassCastException e) {
e.printStackTrace();
}
//endregion
}
/**
* 异常的抛出和传递
* 发生异常时,可通过throw抛出到方法的调用者(对于需要抛出的异常,需要在方法定义时给予声明),也可通过try catch处理异常
* 对于运行时异常,在程序运行时才会被抛出,因此在方法声明中使用throws关键字声明这些异常并不能提高代码的安全性,反而会增加代码的冗余性和复杂性。可以在方法中省略运行时异常的声明。
* 编译时异常不可省略异常的声明
* @param arr
* @param i
* @throws NullPointerException
* @throws ArrayIndexOutOfBoundsException
*/ static void method(int[] arr, int i) throws NullPointerException{//声明可能产生的异常,运行时异常可以省略抛出
//region throw 搭配 if-else 语句可用于异常的手动抛出。对于系统自带的异常,可以自动抛出(即只需在方法声明即可,出现异常自动抛出)
if (arr == null) {
throw new NullPointerException("自定义信息");//抛出一个空指针异常对象,并显示自定义提示信息,抛出异常表示让方法调用者处理
}
//这里的索引越界为系统异常,可省略抛出(上面的NullPointerException也可省略)
// else if (arr.length - 1 < i || i < 0) {
// throw new ArrayIndexOutOfBoundsException("手动抛出");//异常的创建用throw,异常的声明用throws
// }
else {
System.out.println(arr[i]);
}
//endregion
//region try-catch语句用于异常的处理
// try {
// System.out.println(arr[i]);
// } catch (NullPointerException e) {
// e.printStackTrace();
// } catch (ArrayIndexOutOfBoundsException e) {
// e.printStackTrace();
// }
//endregion }
}
class A {
void method() throws Exception {
}
}
/**
* @Description 异常在两个重写方法中的关系
* 重写方法的异常范围小于等于被重写方法
* @Author Noby
* @Date 2023/3/18 17:45
*/class B extends A {
@Override
void method() throws NullPointerException {
}
}
/**
* @Description 类型转换异常
* @Author Noby
* @Date 2023/3/18 18:36
*/class C extends A {
}
自定义异常
package note;
/**
* @Description 自定义异常的使用
* 自定义异常必须手动抛出,自动抛出的异常必须为系统自带的
* 主动抛出:异常通过throw关键字被手动抛出
* 被动抛出:程序中没有通过throw关键字自动抛出
* @Author Noby
* @Date 2023/3/18 18:40
*/public class CustomExceptionNote {
public static void main(String[] args) {
try {
System.out.println(1/0);//自动抛出异常
} catch (Exception e) {
e.printStackTrace();
}
try {
throw new MyThrowable();//主动抛出异常(自定义异常只能通过主动抛出)
} catch (Exception myThrowable) {
myThrowable.printStackTrace();
}
}
}
/**
* @Description 自定义异常
* @Author Noby
* @Date 2023/3/18 19:47
*/class MyThrowable extends Exception {//继承Exception的自定义异常,常用该方法定义自定义异常
public MyThrowable() {
super("自定义异常1");//调用Exception的构造方法,传入的参数为异常的打印信息
}
public MyThrowable(String info) {
super(info);
}
}
