异常
异常:在Java中程序执行过程中发生不正常行为。异常为多种,有算数异常、数组越界异常、空指针异常等(这些是比较常见的异常);
异常的体系结构:
- 数组越界异常: ArrayIndexOutOfBoundsException。
- 空指针异常 : NullPointerException。
- 类型转换异常:ClassCastException。
- 迭代器遍历没有此元素异常:NoSuchElementException。
- 算术异常:ArithmeticException。
- 数字转换异常:NumberFormatException(字符串转换为数字格式错误,IllegalArgumentException的子类)。
- 非法线程状态异常:llegalThreadStateException
- 并发修改异常:java.util.ConcurrentModificationException(多线程下集合操作元素)
- IllegalArgumentException:参数错误(比如方法入参类型错误)
- SecurityException:安全错误(比如权限不够)
- UnsupportedOperationException:不支持的操作错误(比如重复创建同一用户)
- ArrayStoreException:数据存储异常(操作数组时类型不一致)
- java.lang.IllegalStateException{Queue full依然add()添加元素}
- FileSizeLimitExceededException:在SpringBoot中,文件上传时默认单个文件最大大小为1M,当上传一个较大的文件(超出1M)时,运行和后端程序报错
- NoSuchBeanDefinitionException:表示在应用程序中没有找到指定的Bean的定义!在Spring容器ApplicationContext中调用getBean()获取bean对象时,bean的名称填错,就会报改错,或者就跟着没有该Bean对象!
- UnsupportedClassVersionError:比如在JDK8上面运行JDK11环境下的程序!
- java.lang.UnsupportedOperationException异常:使用Collections.unmodifiableCollection(Collection c)方法来创建一个只读集合,这样改变集合的任何操作都会抛出该异常~!
- Java中的所有异常都来⾃顶级父类Throwable,Throwable下有两个⼦类Exception和Error。Throwable类,是所有异常类的根类,Java异常的顶层父类,所有的异常类都是由它继承。
- Exception:异常,程序本身可以处理的异常。
- Java中异常继承的根类是:Throwable。Throwable是根类,不是异常类。
- Exception才是异常类,当程序出现Exception时,是可以靠程序⾃⼰来解决的,它才是开发中代码在编译或者执行的过程中可能出现的错误,它是需要提前处理的,以便程序更健壮!
- 异常体系的最上层父类是Exception。
- Exception的⼦类通常⼜可以分为RuntimeException和⾮RuntimeException两类
- 异常分为两类:编译时异常(受检异常,必须处理)、运行时异常(非受检异常)。
- 受检异常:就是程序必须手动处理的异常,如果不手动处理,则会编译失败。
- 非受检异常:不强制程序处理的异常,不强制你手动处理,无需try...catch...,也无需throws,代码也能编译成功。Error也属于非受检异常。
- 编译时异常{受检异常-Checked Exception}:没有继承RuntimeException的异常,直接继承于Exception。编译阶段就会错误提示 / 报错,必须要手动处理(如果受检查异常没有被 catch或者throws 关键字处理的话,就没办法通过编译),否则代码报错不通过。编译时异常是为了提醒程序员,比如:IOException、ClassNotFoundException、ParseException、SQLException、java.io.FileNotFoundException...
- 运行时异常{非受检异常-Unchecked Exception}:继承了RuntimeException,RuntimeException本身和子类。编译阶段不会报错 / 出现异常提醒,运行时出现的异常。运行时异常是代码出错而导致程序出现的问题。
数组越界(非受检异常)
public class ExceptionDemo {
public static void main(String[] args) {
int[] arr = {10, 20, 40};
System.out.println(arr[0]);
System.out.println(arr[3]); //ArrayIndexOutOfBoundsException
System.out.println("程序截止");
System.out.println(arr[1]);//后面的程序都不执行
}
}
受检异常和非受检异常
public class ExceptionDemo1 {
public static void main(String[] args) throws ParseException {
// 编译时异常(在编译阶段,必须要手动处理,否则代码报错)
String time = "2024年11月18日";
SimpleDateFormat s = new SimpleDateFormat("yyyy年MM月dd日");
System.out.println(s.parse(time));
// 运行时报错(在编译阶段是不需要处理的,是代码运行时出现的异常)
int[] arr = {1, 2, 3};
System.out.println(arr[10]); // 数组越界
}
}
处理异常
处理异常:在Java中有两个处理异常的方式,一个是try...catch...,一个是throws。
try...catch{ 捕获异常 }:将可能发生异常的代码放到try代码块中,然后使用catch来捕获对应的异常。
如果try代码块正常执行,那catch就不会生效;如果发生了指定的异常,则会执行对应的catch代码块,然后继续往下执行,这样我们就能避免异常影响到我们的正常逻辑。捕获异常时还可以接上finally代码块,无论有没有发生异常,finally代码块都会执行。
throws{ 抛出异常 }:在方法上使用throws关键字可以声明该方法可能会抛出的异常。
当我们调用一个方法时,如果这个方法用throws关键字声明了受检异常,此时我们就必须得手动处理它声明的异常,否则就会编译失败{要么你就try...catch...,要么你就在当前方法使用throws声明同样的或其父类异常}。