package Demo_1_26_异常; /* * 异常处理的组合有以下三种: * try...catch * try...catch...finally * try...finally * 处理异常后程序就能正常执行,但是catch()处理异常获取的异常信息并不完整。 * 那么就可以使用printStackTrace()方法获取完整异常信息; * */ public class Main { public static void main(String[] args) { System.out.println("开始!"); try { System.out.println("计算:" + (10/0)); } catch (ArithmeticException e){ // System.out.println("处理异常: " + e); // 处理异常 e.printStackTrace(); }finally { System.out.println("有没有异常都会执行!"); } System.out.println("结束!"); } }
package Demo_1_26_异常; /* * 异常处理的组合有以下三种: * try...catch * try...catch...finally * try...finally * 处理异常后程序就能正常执行,但是catch()处理异常获取的异常信息并不完整。 * 那么就可以使用printStackTrace()方法获取完整异常信息; * */ public class Main { public static void main(String[] args) { System.out.println("开始!"); try { /* * 此时可能出现三种异常: * 1.// 可能出现数组越界异常java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 * 2.// 输入的是字母,数字的转型,可能异常, * 3.// 输入的被除数是0 * 未处理异常,finally都会执行,但是结束输出语句不会执行。异常处理后再执行,结束的输出语句也会执行。 * */ int x = Integer.parseInt(args[0]); int y = Integer.parseInt(args[1]); System.out.println("计算:" + (x/y)); } catch (ArithmeticException e){ e.printStackTrace(); // 获取完整异常信息 }finally { System.out.println("有没有异常都会执行!"); } System.out.println("结束!"); } }
以上程序就需要进行 多异常 的捕获。
package Demo_1_26_异常; /* * 异常处理的组合有以下三种: * try...catch * try...catch...finally * try...finally * 处理异常后程序就能正常执行,但是catch()处理异常获取的异常信息并不完整。 * 那么就可以使用printStackTrace()方法获取完整异常信息; * */ public class Main { public static void main(String[] args) { System.out.println("开始!"); try { /* * 此时可能出现三种异常: * 1.// 可能出现数组越界异常java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 * 2.// 输入的是字母,数字的转型,可能异常, * 3.// 输入的被除数是0 * 未处理异常,finally都会执行,但是结束输出语句不会执行。异常处理后再执行,结束的输出语句也会执行。 * */ int x = Integer.parseInt(args[0]); int y = Integer.parseInt(args[1]); System.out.println("计算:" + (x/y)); } catch (ArithmeticException | ArrayIndexOutOfBoundsException | NumberFormatException e){ // System.out.println("处理异常: " + e); // 处理异常 e.printStackTrace(); // 获取完整异常信息 } finally { System.out.println("有没有异常都会执行!"); } System.out.println("结束!"); } }
异常处理流程:
1、程序运行中才会产生异常,产生异常后将自动进行指定类型的异常类对象的实例化处理;
2、如果此时没有指定的try语句进行异常的捕获,则采用JVM的默认异常处理,打印异常信息并终端程序;
3、如果此时异常被try语句捕获,则在catch语句中进行异常类型的匹配;
4、匹配成功则进行finally语句,失败则进行下一项catch语句的匹配;
5、如果所有catch语句都匹配失败,则在执行完finally语句后进行JVM的默认异常处理,打印异常信息并中断程序;
6,如果在某一个catch语句中匹配成功,则跳转到finally语句,执行完finally语句后程序继续执行至结束。
Throwable异常类:
程序中可以处理异常最大的类型就是Throwable,Throwable下有两个子类:
|·Error:此时程序还未执行时出现的错误,无法处理。
|·Exception:程序中出现的异常,可以处理。
因为对象都能向上转型,这样看来所有的异常 都可以用Exception处理。
当不确定会产生什么异常是就采用这种方法,但是这种方法输出的异常信息并不明确。
(在进行异常捕获的时候必须将范围大的异常放在范围小的异常之后)
Throws异常抛出:
当已经清楚程序的某个方法会出现什么异常的时候,就可以使用throws进行异常的标注。
package Demo_1_26_Throws; /* * 当已经清楚程序的某个方法会出现什么异常的时候,就可以使用throws进行异常的标注。 * * */ public class Main { // 当主方法抛出异常时,就可以不进行异常处理了(一般情况下都是交给主方法进行处理) // 好比厂长(JVM)让经理办事,经理(主方法)找了员工(MyMath方法)去做,然后员工(MyMath方法)出了车祸(异常), // 那么车祸这个异常是员工(MyMath方法)无法处理的,只能交给经理(主方法)处理,但是经理(主方法)是被厂长(JVM)所要求的,那么这个异常就只能交给厂长(JVM)处理了 // 所以只要向上抛出了异常,那么就交给能力更大的人的处理,当事人就做自己的工作 public static void main(String[] args) throws Exception{ try { System.out.println(MyMath.div(1, 2)); }catch (Exception e){ e.printStackTrace(); } } }
throw异常手工抛出:
利用throw关键字进行异常的手工抛出:此时将手动产生一个异常类的实例化对象,并进行异常的处理。
package Demo_1_26_throw; public class Main { public static void main(String[] args) { try { // 异常对象不再是由系统生成的,而是由手动定义的 throw new Exception("自己抛出的对象"); }catch (Exception e){ e.printStackTrace(); } } }
面试题:
请解释throw 与 throws 区别?
throw: 是在代码块中使用的,主要是手工进行异常对象的抛出;。
throws: 是在方法定义上使用的,表示将此方法中可能产生的异常明确告诉给调用处,由调用处进行异常处理。
异常处理的标准格式:
package Demo_1_26_异常标准格式; // 如果要将异常交给调用处处理,则一定要在方法上使用throws抛出异常 public class MyMath { public static int sub(int a, int b) throws Exception{ int tem = 0; System.out.println("【START】资源连接!"); try { tem = a / b; } /*简化catch操作,这种处理格式在资源的访问上尤其重要,需要牢记 catch (Exception e){ throw e; // 向上抛异常 }*/ finally { System.out.println("【END】资源关闭!"); } return tem; } }
package Demo_1_26_异常标准格式; /* * 现在要求定义一个可以实现除法计算的方法,在这个方法之中开发要求如下:. ·在进行数学计算开始与结束的时候进行信息提示; ·如果在进行计算的过程之中产生了异常,则要交给调用处来处理。 * * */ public class Main { public static void main(String[] args) { try { System.out.println(MyMath.sub(10,0)); }catch (Exception e){ e.printStackTrace(); } } }
RuntimeException类:
package Demo_1_26_RuntimeException; public class Main { public static void main(String[] args) { /*parseInt()方法在定义(见API)的时候明确地抛出了异常 * 但是在调用的时候却没有强制性处理 *因为考虑到代码编写的复杂性,所以RuntimeException可以不进行强制性处理。 */ int num = Integer.parseInt("123"); System.out.println(num); } }
面试题:
请解释 RuntimeException与 Exception的区别?
· RuntimeException是 Exception的子类;
· RuntimeException标注的异常可以不需要进行强制性处理,而Exception异常必须强制性处理;
· 常见的RuntimeException异常:NumberFormatException、ClassCastException等
自定义异常类:
有些异常是Java中不会提供的异常,所以需要自己来定义,有两种实现方案:继承Exception或者继承RuntimeException 。
(Exception异常必须处理,RuntimeException异常可选处理)
package Demo_1_26_自定义异常类; public class BoomException extends RuntimeException{ public BoomException(String msg){ super(msg); } }
package Demo_1_26_自定义异常类; public class Food { public static void eat(int num) throws BoomException{ if (num > 10){ throw new BoomException("吃太多了!肚子撑破了!"); }else{ System.out.println("正常吃,不怕吃胖!"); } } }
package Demo_1_26_自定义异常类; public class Main { public static void main(String[] args) throws Exception{ // 当BoomException继承的是Exception时,以下代码就必须处理异常 // 但是当BoomException继承的是RuntimeException时,以下代码就可以不处理代码 Food.eat(11); } }
断言assert:
package Demo_1_26_assert断言; public class Main { public static void main(String[] args) { int x = 10; // 中间会经过许多的x变量的操作步骤 // 断言不会影响程序的执行 assert x == 100: "x的内容不是100"; System.out.println(x); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)