序
前段时间老K分享了Java基础知识讲义系列,包含:JDK基础知识、Java安装和环境配置、变量与常量、Java运算、流程控制、数组、方法、面向对象的封装、继承、多态,以及类与接口等。
最近有越来越多的小伙伴表示希望老K能继续分享后续的内容,因此从今天开始,老K会继续整理Java后续进阶知识的知识点汇总和讲义。
想获取Java基础知识的小伙伴,可以点击下方链接直达:
全网最完整的免费java教程讲义系列(一)——java配置和安装
全网最完整的免费java教程讲义系列(二)——java数据和变量
全网最完整的免费java教程讲义系列(三)——java的运算符
如果你正在学习Java,不妨收藏这篇文章,或者关注我,我会定期分享与Java有关的知识和项目。
下面,我们将开始进阶知识点的第一讲——异常。
一、概念:
a. 定义
异常是程序运行时的错误,会影响程序的正常运行甚至导致程序中断。 合理的异常处理是程序开发中的重要组成部分。 参考阅读:异常_百度百科
b. 比较
. | Error | Unchecked Exception | Checked Exception |
名称 | 错误 | 非检查异常 | 检查异常 |
代表子类 | OutOfMemoryError | RuntimeException | IOException |
原则 | 允许忽略不处理 | 允许忽略不处理 | 必须处理(捕获或向上抛出) |
二、异常捕获
一般是通过try、catch、finally关键词完成对异常的捕获。
a. try
try用于捕获异常,try后面的代码块表示可能会捕获到异常的代码。
b. catch
- catch用于处理异常,catch后面的代码块表示捕获到异常后的处理逻辑;
- 一个try语句可以对应一个或多个catch语句;
- 当try后面没有catch语句,则finally语句必须存在。
c. finally
- finally表示不论是否捕获到异常,都必然执行的代码块;
- 当try后面没有catch语句,则finally语句必须存在;
- finally代码块必然执行;finally代码块必然执行;finally代码块必然执行(重要的事情说三遍);
- 即便try或catch语句中存在return语句,finally代码块里的语句依然会执行;
- 当try/catch语句和finally语句中都存在return语句,则输出结果会参考finally中的return结果,因为finally最后执行并覆盖了前面的输出结果。
d. 示例代码
- 未捕获异常的示例
import java.u; public class ExDemo { public static void main(String[] args) { Scanner sc = new Scanner); Sy("输入a值"); int a = (); Sy("输入b值"); int b = (); Sy("one和two的商是"+(a /b)); Sy("程序可以继续运行..."); } }
- 捕获异常的示例
import java.u; import java.u; public class ExDemo { public static void main(String[] args) { Scanner sc = new Scanner); try { Sy("输入a值"); int a = (); Sy("输入b值"); int b = (); Sy("one和two的商是"+(a /b)); } catch (ArithmeticException e) { Sy("输入错误,除数不能为0"); Sy(e); } catch (InputMismatchException e) { Sy("输入错误,请输入汉字"); e.printStackTrace(); } Sy("程序可以继续运行..."); } }
- 代码详解:
- 当“未捕获异常的示例”中的除数为0,或者输入数据不为int时,最后的程序可以继续运行...语句不会输出;
- 捕获异常的示例中,会通过try...catch...语句捕获上述异常;
- 上例中,通过多重catch语句,能实现异常的差异化处理;
- 可以通过printStackTrace()方法,展示捕获异常的详细信息;
- 无论是否有异常被捕获,最后的程序可以继续运行...语句都会输出。
- 阅读异常
当上例中输入数据不为int时,会提示如下stack trace信息:
Exception in thread "main" java.u at java.u.throwFor(Scanner.java:864) at java.u.next(Scanner.java:1485) at java.u.nextInt(Scanner.java:2117) at java.u.nextInt(Scanner.java:2076) at ExDemo.main(ExDemo.java:9)
- 异常信息反映了代码的调用关系;
- 异常信息最后一行代表发生异常的最外层代码,向上每行都向内回溯一层代码;
- 上例中ExDemo.java:9表示异常发生在ExDemo.java文件下的第9行代码附近。
三、抛出异常
a. throws
1. 概念
- throws关键字需要应用在方法声明的语句上;
- throws关键词表示抛出异常给调用此方法的方法,当前方法并不处理该异常;
- 当一个方法抛出检查异常(Checked Exception),调用这个方法的方法必须①捕获处理该异常或②向上抛出该异常;
注意:throws和throw的区别,本节提到的是throws关键字
语句:public void method() throws Exception1, Exception2 {...}
2. 示例代码
public class ExDemo { public static void main(String[] args) { div(12, 0); } public static void div(int a, int b) throws Exception { Sy("one和two的商是" + (a / b)); } }
- 当编译上述代码时,编译器会识别main方法中的dev语句编译错误,原因是dev方法向外抛出的Exception异常并未被main方法捕获处理;
public class ExDemo { public static void main(String[] args) { try { div(12, 0); } catch (Exception e){ e.printStackTrace(); } } public static void div(int a, int b) throws Exception { Sy("one和two的商是" + (a / b)); } }
- 在main中捕获处理dev方法下的异常,编辑错误就会消失。
b. throw
1. 概念
- 通过throw,可以抛出一个异常对象;
- throw语句一般是在方法体中使用;
- 通过throw,可以根据自己的业务逻辑设置异常对象。
2. 比较
. | throw | throws |
标准语句 | throw new 异常类型(参数列表) | throws 异常类型列表 |
处理方法 | 1. 用try...catch...捕获处理;2. 通过throws向上抛出异常 | 1. 调用该方法的方法复杂处理异常 |
两者联用注意事项 | throw抛出的异常范围要小于throws的异常范围 | throws抛出的异常范围要大于throw的异常范围 |
3. 示例代码
public class ExDemo { public static void main(String[] args) { try { // 将b设置为1,触发div异常 div(12, 1); } catch (ArithmeticException e) { e.printStackTrace(); } } public static void div(int a, int b) throws ArithmeticException { // 通过throws向上抛出代码块中throw的异常 if (b == 1) { // 用throw抛出一个异常对象 throw new ArithmeticException("一个数除以1就是它自己"); } else { Sy("one和two的商是" + (a / b)); } } }
- 这里,我们自定义了一个算术异常,不允许除数为1,因为结果就是被除数本身;
- 通过throw我们抛出的异常对象被throws向上抛出给了调用div的main方法,并由main方法捕获处理这个算术异常ArithmeticException。
c. 自定义异常
1. 概念
定义一个类,使之继承自Throwable类或其子类。
Throwable是Error和Exception的父类,相关文档:Throwable (Java Platform SE 8 )
2. 示例代码
- ExDemo.java
public class ExDemo { public static void main(String[] args) { try { div(12, 1); } catch (DivideOneException e) { // ArithmeticException改为DivideOneException e.printStackTrace(); } } public static void div(int a, int b) throws DivideOneException { // ArithmeticException改为DivideOneException if (b == 1) { throw new DivideOneException(); // ArithmeticException改为DivideOneException } else { Sy("one和two的商是" + (a / b)); } } }
- DivideOneExce
public class DivideOneException extends ArithmeticException { public DivideOneException() { super("一个数除以1就是它自己"); // 编写你自己的异常信息和逻辑代码... } }
说明:
- 我们自定义一个“除数为1”的算术异常DivideOneException,继承自ArithmeticException;
- 在DivideOneExce中可以根据业务加入自定义的代码逻辑;
- 我们将之前的案例稍作调整,形成本例中的ExDemo.java;
- 完成后,本例上述代码就能起到上例一样的效果,甚至拥有自定义的异常代码逻辑。
结束语
我是专注于开发领域的@老K玩代码,会持续生产关于如何学习编程语言的优质内容。
如果你想学习编程,或者想精进你的编程能力,可以关注我。
如果你对开发、编程有任何疑问或有想了解的内容,而我暂时没有写到的,也欢迎随时来找我聊聊。
#头条创作挑战赛#