java 异常基础 万字详解(通俗易懂) |
您所在的位置:网站首页 › java异常产生的原因 › java 异常基础 万字详解(通俗易懂) |
目录 一、前言 二、异常概述: 三、异常分类: 1.前言 2.异常(Exception): ①定义: ②编译期异常和运行期异常: ③代码演示: 3.错误(Error): ①概述: ②代码演示: 四、异常的产生机制(重要): 异常的产生过程: 代码演示: 图解演示: 五、异常相关: 1.关于throw关键字: ①前言 ②作用: ③使用格式: ④使用throw关键字的三个注意事项: ⑤代码演示: 2.关于Objects类的静态方法: ①前言: ②介绍: ③代码演示: 六、异常处理(重要): 1.JVM的默认处理方式: 2.常见的两种处理方式: ①通过throws关键字: 代码演示: ②通过try...catch方法: 代码演示: 3.Throwable类中的三个常用异常处理方法: ①三个常用方法: ②代码演示: 4.finally代码块: ①格式: ②注意事项: ③代码演示: 七、java 异常进阶: 八、完结撒❀: 一、前言大家好,今天给大家带来一篇java 异常基础的万字详解,希望通过举栗和讲解,帮助初学者快速了解并能上手java异常,以便继续学习javaFile类,javaIO流和java反射(大家有兴趣可以看看我写的File,IO流,反射的万字详解系列),注意代码中的注释也很重要。up的所有文章都会适时修改和补充,以更完善。良工不示人以朴,感谢阅读!(PS:点击目录可以跳转)。 二、异常概述:①异常,即程序编译过程中或运行过程中出现的非正常情况,通俗地说,异常就是程序出现的非语法错误,最终会导致JVM的非正常停止。 ②异常并不是语法错误,语法错了,编译不通过,不会产生字节码文件,压根不能运行。 三、异常分类: 1.前言java中Throwable类是所有异常和错误的超类(父类),即异常的顶层父类。Throwable类属于java.base模块,java.lang包下。它下面有两个子类Error和Exception,前者是错误,后者就是我们常说的异常🌶。来张图直观一点: 指合理的应用程序可能需要捕获的问题,是可以通过常用处理机制来解决的。 eg:NullPointerException(空指针异常) ArithmeticException(运算条件异常) ②编译期异常和运行期异常:Δ异常又可以分为编译期异常和运行期异常: 编译期异常,即进行编译时出现的问题。我们必须采取相应的处理机制。 运行期异常,即代码运行中出现的问题。我们可以不处理,默认交给JVM来处理。说到运行期异常就不得不说到Exception类下面的一个子类,RuntimeException。RuntimeException和RuntimeException下的所有子类异常都属于运行期异常。来张图看看RuntimeException下的子类究竟有多少,如下图: 查询API可以得知,直接已知的子类数目已经相当惊人!其实,我们平时常见的(运行期)异常,很多都是RuntimeException的子类,眼尖的小伙伴儿们估计也能在图里面发现几个熟人了。 ③代码演示:我们先在exception包下创建一个IntroException类作为演示类,如图: IntroException类代码如下: package knowledge.exception; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.Reader; public class IntroException { public static void main(String[] args) throws FileNotFoundException { //异常(Exception)举栗: //1) 编译期异常举栗: Reader reader = new FileReader("D:/JAVA/IDEA/file/1.txt"); /* 此处就有异常提示,未处理的异常:java.io.FileNotFoundException. (找不到文件异常)出现该异常的原因是程序认为你传入的路径可能是瞎写的。 可通过抛出异常解决。假如传入的路径不匹配,就是JVM的默认处理方式了 */ //2) 运行期异常举栗: //这里我们先将代码写到了try...catch语句的外面,不对它进行处理。 int[] array = new int[4]; System.out.println(array[4]); /* 执行到输出array[4]的代码时会报ArrayIndexOutOfBoundsException, 即数组下标越界异常; 这是因为该数组长度为4,索引范围是0~3,不可能出现4的索引。 因此代码执行到这里时就会报异常。 */ /* (try...catch...可以捕获异常,我们后面会讲到,先让大家认识一下) */ try { //可能会出现异常的代码 System.out.println("👴非要看看第五个元素:" + array[4]); } catch (Exception e) { //异常的处理逻辑 System.out.println(e); } finally { System.out.println("非要看不存在的元素?"); } } }注意,对于编译期异常,只要出现,编译器就会即时报出异常,表现为用红色的波浪线标注出来,如下图所示: 这时候代码是不能运行的,因为只要你按下运行键,控制台会显示提示 : 必须对这个编译期异常作出相应的处理机制。如下图: 所以, 我们得到结论,出现编译期异常时,我们必须进行相应的处理,否则程序无法运行。此处我们采取直接抛出异常的方式,即在方法声明处加上throws + 要抛出的异常的名字。如下图所示: 接下里我们把 Reader reader = new FileReader("D:/JAVA/IDEA/file/1.txt"); 这句代码注释掉,看看运行期异常是怎么回事,运行结果如下图: JVM也是毫不留情的告诉我们出现异常了,它打印的是抛出的异常对象,内容:ArrayIndexOutOfBoundsException(数组下标越界异常) ,原因:索引4超过了长度为4的数组的索引范围。位置:main方法中的第52行出现了问题。(下文异常的产生机制中会详细解释) 接着我们把出问题的代码放在try...catch语句中看看会发生什么?(try...catch...可以捕获异常,我们后面会讲到,先让大家认识一下)如下GIF图: 运行结果: 可以看到,经过我们处理后,JVM没有再用红色的字体在控制台打印出异常对象。 3.错误(Error): ①概述:指合理的应用程序不应该试图捕获的,严重的问题,是不可以通过常用处理机制来解决的。 eg1:StackOverFlowError(栈内存溢出) eg2:OutOfMemoryError(内存溢出) Δ发现了没有? 异常以Exception作结尾,而错误以Error作结尾。 ②代码演示:我们先在exception包下,创建一个IntroError类作为演示类,如图: IntroError类代码如下: package knowledge.exception; import java.io.FileNotFoundException; public class IntroError { public static void main(String[] args) throws FileNotFoundException { //错误(Error)举栗: int[] arrayTest = new int[1024 * 1024 * 1024]; /* OutOfMemoryError: java heap space, 注意结尾是Error了. 内存溢出的错误,数组所占的内存太大,超出了给JVM分配的内存 解决方法:必须修改代码中引起错误的部分 */ System.out.println("必须修改掉代码中引起错误的部分,这句话才能成功打印出来。"); System.out.println("----------------------------------------"); } }注意,这里我们定义了一个长度巨**离谱的数组,显然这会对内存造成负担,让我们看看运行结果如何,如图: 噢,他提示我们内存溢出了,而原因是堆空间溢出了,这是因为数组通过new关键字,在堆空间中创建新的内容,堆空间是有限的,我们申请的数组长度太长,当然会溢出。而数组名本身不过是一个指向罢了,或者叫做引用,指向堆中申请的这片空间。 接下来我们把数组长度改小,看看情况会不会好一点儿,如下GIF图所示 : 显然,在数组长度[1024 * 1024 * 1024] 中去掉一个1024后就没有再报错了。 四、异常的产生机制(重要): 异常的产生过程:1.程序执行到代码异常处时,JVM检测出程序出现异常,这时它会 根据异常产生的原因创建一个异常对象,这个异常对象包含了异常产生的(原因,内容,位置) 2.若异常所在的方法中没有相应的异常处理机制,那么JVM就会把 异常对象抛给方法的调用者(此处为main方法)来处理这个异常 3.main方法接收到了这个异常对象后,若main方法也没有异常处理机制, 就会继续把main方法抛给它的调用者(即JVM)来处理。 4.当JVM收到main方法抛来的这个异常对象后,它会在控制台打印出这个异常对象,并终止程序. 代码演示:我们先在exception包下创建一个Process类作为演示类,如图: Process类代码如下: package knowledge.exception; import java.util.Scanner; /** JVM默认的异常处理方式: 创建对应异常类的对象,并抛出一个异常对象. 在控制台打印异常信息,并终止程序. */ public class Process { public static void main(String[] args) { //1.定义一个数组 int[] array = {1, 2, 11, 2, 23}; System.out.println("正常情况下的遍历数组:"); printArr(array); Scanner sc = new Scanner(System.in); System.out.println("输入你想指定的索引,根据索引获取数组的指定内容:"); int index = sc.nextInt(); //我们故意输入一个不存在的索引 getAssignedElement(array, index); /* 先把代码看完,再跟着看注释! 第一步,执行到getAssignedElement(array, index);这条代码时,JVM 便检测出异常,并创建了一个包含异常内容,原因以及位置的异常对象 */ /* 第二步,若异常所在的方法中没有相应的异常处理机制,那么JVM就会把 异常对象抛给方法的调用者(此处为main方法)来处理这个异常 */ /* 第三步, new ArrayIndexOutOfBoundsException("5"); main方法接收到了这个异常对象,若main方法也没有异常处理机制, 就会继续把main方法抛给它的调用者,即JVM处理 */ /* 第四步, 当JVM收到main方法抛来的这个异常对象后,它会在控制台打印出 这个异常对象,并终止程序 */ sc.close(); } //2.定义一个方法来遍历数组 /* 标准的i < arr.length , 因此该方法无数组下标越界异常。 */ public static void printArr(int[] arr) { for (int i = 0; i < arr.length; ++i) { System.out.println(arr[i]); } } //3.定义一个方法来获取数组指定索引处的元素。 public static void getAssignedElement(int [] arr, int index) { System.out.println(arr[index]); /* 假设我们传入的索引是5,而我们所定义的数组一共只有五个元素,索引是0~4, 是没有5这个索引的,所以运行到这里时,JVM就会检测处程序出现异常。 这时,JVM会做两件事: 1) JVM会根据异常产生的原因创建一个异常对象,这个异常对象包含了 异常产生的(原因,内容,位置),eg:new ArrayIndexOutOfBoundsException("5"); 2) 由于在getAssignedElement方法中没有相应的异常处理机制,那么 JVM就会把异常对象抛给方法的调用者,即main方法来处理这个异常 */ } } /* new ArrayIndexOutOfBoundsException("5"); 当JVM收到 main方法抛来的这个异常对象后,它又要做两件事: 1) 把异常对象(内容,原因,位置)以红色的字体打印在控制台 2) JVM终止程序 eg : ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 5 内容:数组下标越界异常 原因:咱们指定的索引不合法 位置:Process.java:___ */运行结果如下GIF图 : 注意,throw关键字和throws关键字长得像,但可不是一回事儿,不要混淆了。前者是在指定方法中抛出异常对象,而且可以自己更改提示信息,后者则是常用的异常处理方式之一。 了解即可,重要的是把代码都能看懂了。 ②作用:可以使用指定的关键字在指定的方法中抛出指定的异常对象 ③使用格式:throw new ____Exception("异常产生的原因"); PS:其实“异常产生的原因这里”,你可以随便写你想写的提示内容。 ④使用throw关键字的三个注意事项:1) throw关键字必须写在方法的内部 2) new出来的对象必须是Exception 或者 Exception 的子类对象 3) throw关键字抛出指定的异常对象,对该异常情况的具体处理情况如下 : Δ若throw出的是运行期异常,即创建的RuntimeException 或 RuntimeException的子类对象, 我们可以不处理,默认交给JVM处理,(打印异常对象并终止程序) Δ若throw出的是编译期异常,即写代码的时候出现了异常,我们就必须处理这个异常,而处理的方式, 要么是throws, 要么是try...catch ⑤代码演示:我们先在exception包下创建一个ThrowKey类作为演示类,如图: ThrowKey类代码如下: package knowledge.exception; /** 实际开发中,我们必须首先对方法传递过来的参数进行合法性校验 如果参数不合法,我们就必须通过抛出异常来告知方法的调用者:传递的参数有问题 eg: 如下,如果数组指向为空,我们就 通过throw new nullPointerException(抛出空指针异常) 的方式来通知调用者。 */ public class ThrowKey { public static void main(String[] args) { int[] array1 = null; int[] array2 = {1, 2, 3, 4, 5}; int element = getElement(array1, 2); //传入一个空引用作测试 int element2 = getElement(array2, 5); //传入一个不存在的索引作测试 } //定义一个方法,用来获取数组中的元素。 public static int getElement(int[] arr, int index) { //先对数组这个引用作检验: if (arr == null) { throw new NullPointerException("传过来的数组是空的,检查一下是否传错了!"); /* 由于nullPointerException(空指针异常)是运行期异常, 因此我们可以不用管,默认交给JVM处理即可。 */ } //再对索引参数进行合法性检验, /* 如传入的索引超出了数组索引的范围,我们就可以通过 throw new ArrayIndexOutOfBoundsException(抛出数组下标越界异常)的方式来告知 方法的调用者:传入的索引不在数组的正常索引范围内。 */ if (index >= arr.length || index < 0) { throw new ArrayIndexOutOfBoundsException("你干嘛~ 数组的索引最大就是(数组的长度-1)"); /* 由于ArrayIndexOutOfBoundsException(数组下标越界异常)是运行期异常, 因此我们可以不用管,默认交给JVM处理即可。 */ } return arr[index]; } }看一下运行效果: 发现没有?我们通过throw关键字抛出的异常对象成功打印了出来,并且我们写入的提示信息也跟着打印了出来,牛逼!🐂🐂🐂 接下来我们把测试1的代码注释掉,进行测试2:即数组引用正常,但传入的索引不正常,会怎么样?运行效果如下gif图: 可以看到我们的提示信息再次成功打印出来! 2.关于Objects类的静态方法: ①前言:前面我们说过,在实际开发中,带参方法要对传入的参数进行合法性检验。然而,gosling早就设置了懒人青睐的方法,都给你写好了,你还需要自己写吗?懒人有懒福(bushi) ②介绍: Objects类属于java.base模块,java.util包下,继承自Object类。我们要用到它里面的静态方法requireNonNull(T obj),该方法可以判断传入的对象是否为空, 常用的还有它的一个重载的方法是requireNonNull(T obj, String message) ,判断是否为空的同时,还可以在判断为空的情况下修改打印出的异常对象的原因(即提示信息)。大家也可以去查看API,我截个图放下面: 可以看到第一个静态方法可以检查指定的对象引用是否为空,如果为空则抛出空指针异常;第二个方法(与第一个方法重载)则可以在第一个方法的基础上抛出自定义的空指针异常。 ③代码演示:我们先在exception包下创建一个JudgeNull类作为演示类,如图: JudgeNull类的代码如下: package knowledge.exception; import java.util.Objects; /* * Objects类中用于判断对象是否为空的静态方法: * 源码: * public static T requireNonNull(T obj) { * if (obj == null) { throw new NullPointerException(); * } * return obj; * } * //当我们对传入的参数进行合法性校验时,可直接调用此方法,就无需再自己来判断了 * */ public class JudgeNull { public static void main(String[] args) { //1.使用我们以往的方法: testMethod(null); /* 运行结果: JVM会打印出对应的异常对象,并且携带有我们的提示信息。 */ //2.使用Objects类的静态方法: newMethod(null); } public static void testMethod(Object obj) { //1.以往我们对参数进行合法性检验, 判断它是否为空时: if (obj == null) { throw new NullPointerException("该引用为空!"); } return; } public static void newMethod(Object obj) { //2.时代变了,我们可以直接调用Objects类的静态方法: /* 需注意:该方法还有两个常用的重载: 1)Objects.requireNonNull(obj); 2)Objects.requireNonNull(obj, message); //方法2)与 1)相比,多传入一个String类型,表示要打印出的提示信息 */ //eg: Objects.requireNonNull(obj); //Objects.requireNonNull(obj, "传入对象的引用为空!"); return; } }1) 我们先来测试一下以往使用throw关键字的常规方法,运行效果如下gif: 2) 再来测试 一下Objects类的静态方法,运行效果如下gif: 3) 最后测试一下Objects的重载方法,效果如下gif图: 六、异常处理(重要): 1.JVM的默认处理方式: 创建对应异常类的对象并抛出一个异常对象,然后JVM会以红色的字体在控制台打印出错误信息,并终止程序。 2.常见的两种处理方式: ①通过throws关键字:通过throws关键字将异常抛给调用者,最终抛给JVM,JVM做中断处理。 格式: 在方法声明时使用: 修饰符 返回值类型 方法名() throws ___Exception { [//throw new XxxException();]...... } 注意事项: Δthrows关键字必须写在方法声明处(与throw作区分) Δthrows关键字后面声明的异常必须是 Exception 或 Exception的子类 Δ如果抛出的异常有子父类关系,直接声明父类即可(即直接抛出异常的父类),特别适用于出现多个编译期异常且这些异常有统一具体的父类时,比如在java反射或者javaIO流中常见。 Δ若调用的方法抛出了异常,我们就必须处理声明的异常,要么接着抛,直到抛给JVM,要么就用之后要讲到的try...catch...方法 代码演示:我们现在exception包下创建一个HandlingOne类作为演示类,如图: HandlingOne类代码如下: package knowledge.exception; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.Reader; public class HandlingOne { public static void main(String[] args) throws Exception{//接着抛,main 函数会抛给JVM. //需求1: 调用testH() 方法 //因为testH方法已经抛出了一个异常,所以作为调用者(main函数) 必须处理这个异常,有两种处理方案 //方案一: 接着抛 main函数会抛给JVM testH(); //方案二: try..catch...(等会儿再讲) //需求2: 调用readData() 方法 //readData("D:\\FUCK"); } //定义一个测试方法testH(): public static void testH() { int a = 211 / 0; System.out.println("The value of a is :" + a); //会抛出ArithmeticException异常,但ArithmeticException是运行期异常,所以可以不处理 } //再来举个栗子: public static void readData(String fileName) throws FileNotFoundException { /* 这里针对throw抛出的异常对象,我们选择了继续抛,抛给main方法 */ //对传入的参数进行合法性检验,判断其是否为d盘下file文件夹里的文件。 if (!fileName.startsWith("D:\\JAVA\\IDEA\\file")) { throw new FileNotFoundException("你传入的路径有可能是瞎🐔8写的!"); /* FileNotFoundException属于编译期异常,因此必须对该异常进行处理。 此处我们通过throws关键字抛给该方法的调用者,即抛给了main方法 */ } Reader reader = new FileReader(fileName); reader.close(); //...... } }I.我们先来测试一下testH() 方法,即常规的参数合法性检验,运行结果如下图: 可以看到当我们试图让除数为0时,JVM在控制台上打印出了ArithmeticException,运算异常。 II.我们再来测试一下readData() 方法,运行效果如下gif图: 通过try...catch...方法自己来捕获并处理异常 格式: (代码中的注释更详细) try { //尝试执行的代码 } catch (Exception) { //异常处理的逻辑 }....... 注意事项: 1.try中可能会抛出多个异常对象,那么就可以使用多个catch语句来处理这些异常对象 2.如果try中产生了异常,那么该异常就会被catch语句捕获,并执行catch语句中相应的处理逻辑,反之则不执行catch语句;try...catch...语句执行完之后,会继续正常执行之后的代码。 代码演示:我们先在exception包下创建一个HandlingTwo类作为演示类,如图: HandlingTwo类代码如下: package knowledge.exception; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; /* 常用异常处理方式二: 通过try...catch...方法自己来捕获并处理异常 格式: try { //尝试执行的代码(可能出现的异常) } catch (Exception e) { //括号中要定义一个异常类型的变量,用来接收try中捕获的异常 //异常的处理逻辑,即出现可能的异常之后的处理代码 //一般在实际开发中,会将异常的信息记录到一个日志中 } catch (异常类型 异常变量) { ......//多个catch语句格式一致 } ...... 注意事项: 1.try中可能会抛出多个异常对象,那么就可以使用多个catch语句来处理这些异常对象 2.如果try中产生了异常,那么该异常就会被catch语句捕获, 并执行catch语句中相应的处理逻辑,反之则不执行catch语句;try...catch...语句 执行完之后,会继续正常执行之后的代码 */ public class HandlingTwo { public static void main(String[] args) { //readText("D:\\JAVA\\IDEA\\file\\1.txt"); /* 直接调用readText方法,由于该方法抛出了IOException, 而IOException是编译期异常,所以如果这时直接运行程序,IDEA会直接显示: 未处理的异常: IOException 这次,我们不再退缩!直接使用try...catch语句重拳出击. */ try { //可能出现异常的代码 readText("D:\\JAVA\\IDEA\\file\\1.ttt"); } catch (IOException ioE) { //对捕获到的异常进行逻辑处理的代码 System.out.println("你传入的路径不对哈"); } System.out.println("只有try...catch...执行完后,这句话才会打印出来!"); } //定义一个方法用来读取一个文本文件的内容 public static void readText(String fileName) throws IOException{ if (!fileName.endsWith(".txt")) { throw new IOException("传入的路径不是文本文件!"); /* 此处抛出了IOException,是编译期异常,必须对throw抛出的异常进行处理, 我们用throws关键字抛给main方法。 */ } System.out.println("嗡嗡,你是对的!"); BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName)); String data; while ((data = bufferedReader.readLine()) != null) { System.out.println(data); } bufferedReader.close(); } }I.我们先传入一个不是以".txt"结尾的路径,看看输出情况如何,如下图: 可以看到,是catch中的语句成功打印出了路径错误的提示信息。 II.我们再传入一个正确的路径看看输出效果,如下gif图: 成功读取了1.txt文本文件中的内容并打印了出来 。 3.Throwable类中的三个常用异常处理方法: ①三个常用方法:以下三个方法可用于try...catch...语句中的catch语句里面,作为异常处理逻辑。 I.String getMessage() 返回此throwable的简短描述 II.String toString() 返回此throwable的详细消息字符串 III.void printStackTrace() JVM打印异常对象,默认此方法,打印的异常信息是最全面的。(注意返回值是void类型) ②代码演示:我们先在complement包下创建一个ThreeWay类作为演示类,如图: ThreeWay类代码如下: package knowledge.exception.complement; import java.util.Objects; public class ThreeWay { public static void main(String[] args) { try { int[] array = {1, 2, 3, 4, 5}; getElement(array, 5); /* 定义的数组array索引是0~4,因此传入索引5一定会出问题。 */ } catch (ArrayIndexOutOfBoundsException indexE) { System.out.println("测试第一种方法如下:\n" + indexE.getMessage()); System.out.println("测试第二种方法如下:\n" + indexE.toString()); System.out.println("直接打印异常会如何?\n" + indexE); System.out.println("测试第三种方法如下:" ); indexE.printStackTrace(); } } public static int getElement(int[] arr, int index) { Objects.requireNonNull(arr, "This pointer is null"); int element = arr[index]; return element; } }运行结果 : 由运行结果我们可以得知: 方法一二三,一个比一个详细。而直接打印异常对象则默认使用 toString() 方法,即返回throwable的详细消息字符串。 4.finally代码块:finally代码块是对try...catch...语句的补充和完善,finally中的代码一定会执行。 ①格式:try { //尝试执行的代码 } catch (Exception e) { //异常的处理逻辑(解决方法) } finally { //无论是否出现异常,都会执行的代码 } ②注意事项:1) finally 不能单独使用,必须与try..catch...语句一起 2) finally 一般用于资源释放 OR 资源回收,无论程序是否出现异常,最后都要释放资源(常见于IO流)。 ③代码演示:我们先在complement包下创建一个AboutFinally类作为演示类,如图: AboutFinally类代码如下: package knowledge.exception.complement; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class AboutFinally { public static void main(String[] args) { try { readText(""); } catch (IOException ioE) { ioE.printStackTrace(); } finally { System.out.println("释放资源!"); } } //定义一个方法用来读取传入的文本文件中的内容。 public static void readText(String fileName) throws IOException { //直接抛出父类异常 //进行判断,如果传入的路径不是文本文件,就提示它路径不合法 if (!fileName.endsWith(".txt")) { throw new IOException("你输入的路径不合法"); } //判断成功就开始读取文件 //1.创建子符缓冲流对象,关联数据源文件 BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName)); //定义变量,记录读取到的内容 String lineData; //循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量 while ((lineData = bufferedReader.readLine()) != null) { System.out.println(lineData); } //释放资源 bufferedReader.close(); } }运行结果: 我们先传入错的路径,看看结果如何: 可以看到,即使JVM打印出了异常对象后,“释放资源” 仍然打印在了后面. 接下里我们传入一个正确的路径试试,如下gif: java异常基础到这儿差不多就能上手了,java异常进阶准备与大家分享一下多异常的处理,自定义异常的使用等等内容,链接在这儿: (正在写,写完放链接!) 11.26已更新:java 异常进阶 多异常和自定义异常详解。 八、完结撒❀:恭喜你,看到这你肯定已经可以上手java异常类了!up还有其他关于javaSE基础的万字详解系列,有兴趣可以去我的博客看看,感谢阅读! PS : 2023.5.26作了略微的修改。 System.out.println("---------------------------------------------------------------------------------"); |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |