JavaSE系列Java异常处理机制
Posted 未见花闻
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE系列Java异常处理机制相关的知识,希望对你有一定的参考价值。
⭐️前面的话⭐️
本篇文章带大家认识Java基础知识——异常,在理想的情况下,用户输入的数据格式永远是正确的,一个程序也许可能永远没有bug,但是在实际情况当中,这种理想的情况非常少,用户输入数据格式出现错误是非常常见的,需要一种机制解决类似的问题,而在Java中引入了异常的概念,本篇博客将围绕什么是异常,异常怎么解决两个维度对异常做一个详细地分析。
📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2021年12月8日🌴
✉️坚持和努力一定能换来诗与远方!
💭参考书籍:📚《Java核心技术》,📚《Java编程思想》,📚《Effective Java》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🙏作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
📌导航小助手📌
1.初见Java异常
1.1熟悉的面孔
在Java的学习过程中,一定遇到过除数为0,数组越界,对空引用操作等,这些情况可以通过编译,但是在运行的时候编译器会报出异常,这些异常就是Java异常机制中的一部分。
System.out.println(10 / 0);//除数为0
int[] arr = new int[10];
System.out.println(arr[11]);
String str = null;
System.out.println(str.length());
A
r
i
t
h
m
e
t
i
c
E
x
c
e
p
t
i
o
n
,
A
r
r
a
y
I
n
d
e
x
O
u
t
O
f
B
o
u
n
d
s
E
x
c
e
p
t
i
o
n
,
N
u
l
l
P
o
i
n
t
e
r
E
x
c
e
p
t
i
o
n
ArithmeticException,ArrayIndexOutOfBoundsException,NullPointerException
ArithmeticException,ArrayIndexOutOfBoundsException,NullPointerException都是初学Java时常遇到的一部分异常,但是Java异常机制包括的不仅仅只有异常,还有错误也是属于Java异常机制范围内的。
1.2防御式编程
错误在代码中是客观存在的. 因此我们要让程序出现问题的时候及时通知程序猿, 我们有两种主要的方式:
LBYL: Look Before You Leap. 在操作之前就做充分的检查.
EAFP: It’s Easier to Ask Forgiveness than Permission. “事后获取原谅比事前获取许可更容易”. 也就是先操作, 遇到问题再处理.
打个比方,有一天你心血来潮,看到一位非常漂亮的小姐姐,你很想牵她的手,但是你非常的有礼貌,先询问这位小姐姐:我能牵你的手吗?,这位小姐姐毫不犹豫地说:不行!,这一种情形就是LBYL方式;与此同时,另一位比较强悍的兄弟也想牵这位小姐姐的手,于是直接拿起这位小姐姐的手,牵了起来,然后这位小兄弟被扇了一巴掌,这种情形就是EAFP方式。
Java异常核心思想就是EAFP。
1.3异常的优点
使用异常能够更好地处理业务,代码也更有条理,更加清晰明白,不使用异常代码正常的代码与可能异常的代码混在一起,比较混乱。
比如一个模拟实现一个游戏开始的过程:
不使用异常:
public class Test2
public static void main(String[] args)
boolean ret = false;//账号密码匹配结果
ret = 密码验证结果();
if (!ret)
//处理游戏登录失败业务
ret = 加载游戏结果();
if (!ret)
//处理加载游戏失败业务
ret = 联机匹配结果();
if (!ret)
//处理联机匹配失败业务
ret = 氪金是否成功结果();
if (!ret)
//处理氪金失败业务
使用异常:
public class Test2
public static void main(String[] args)
try
密码验证();
加载游戏();
联机匹配();
氪金();
catch (密码验证异常)
//处理密码错误异常
catch (加载游戏异常)
//处理加载游戏异常
catch (联机匹配异常)
//处理联机匹配异常
catch (氪金异常)
//处理氪金异常
2.异常处理
2.1捕获异常
想要捕获一个异常,前提需要知道可能会发生什么类型的异常,最常见的异常就是前面所举例的
A
r
i
t
h
m
e
t
i
c
E
x
c
e
p
t
i
o
n
,
A
r
r
a
y
I
n
d
e
x
O
u
t
O
f
B
o
u
n
d
s
E
x
c
e
p
t
i
o
n
,
N
u
l
l
P
o
i
n
t
e
r
E
x
c
e
p
t
i
o
n
ArithmeticException,ArrayIndexOutOfBoundsException,NullPointerException
ArithmeticException,ArrayIndexOutOfBoundsException,NullPointerException分别为除数为0异常,数组越界异常,空指针异常。
当然,Java异常体系中的异常种类非常多,Exception类下的直接子类就有:
RuntimeException类是目前我们接触最多的,前面列举的几个常见的异常都是该类的子类。
2.1.1捕获一个异常
我们在进行除法计算时,可能会出现除数为0,访问数组对象时,可能出现数组越界,使用一个对象时,可能会出现空指针异常,知道一段代码可能出现某种或某些异常,我们可以对异常进行捕获,语法规则为:
try
//可能出现异常的代码段
catch (异常类 异常变量名)
//处理该异常
try
代码块中放的是可能出现异常的代码。
catch
代码块中放的是出现异常后的处理行为。
public class Test3
public static void main(String[] args)
int a = 0;
try
System.out.println(8 / a);
catch (ArithmeticException e)
System.out.println("捕捉到了除数为0异常!");
int[] arr = new int[10];
try
System.out.println(arr[20]);
catch (ArrayIndexOutOfBoundsException e)
System.out.println("捕捉到了一个数组越界异常!");
String str = null;
try
System.out.println(str.equals("aaa"));
catch (NullPointerException e)
System.out.println("捕捉到了一个空指针异常!");
可以调用异常类中的
p
r
i
n
t
S
t
a
c
k
T
r
a
c
e
(
)
方
法
printStackTrace()方法
printStackTrace()方法打印异常错误信息:
public class Test3
public static void main(String[] args)
int a = 0;
try
System.out.println(8 / a);
catch (ArithmeticException e)
e.printStackTrace();
System.out.println("捕捉到了除数为0异常!");
int[] arr = new int[10];
try
System.out.println(arr[20]);
catch (ArrayIndexOutOfBoundsException e)
e.printStackTrace();
System.out.println("捕捉到了一个数组越界异常!");
String str = null;
try
System.out.println(str.equals("aaa"));
catch (NullPointerException e)
e.printStackTrace();
System.out.println("捕捉到了一个空指针异常!");
如果异常没有被主动捕捉(使用try…catch语句捕捉),这个异常会交给JVM处理,一旦交给JVM处理,发生异常,将非正常终止程序,后续代码不会执行。
public class Test6
public static void main(String[] args)
int[] arr = new int[10];
System.out.println(arr[20]);//发生数组越界异常,该异常没有被捕获,将交给JVM处理
System.out.println("我是异常代码的后续代码,我被执行了!");
代码非正常退出,异常处后的代码不会被执行!
主动捕获异常,异常处后面的代码会执行,并且程序正常退出:
public class Test5
public static void main(String[] args)
int[] arr = new int[10];
try
System.out.println(arr[20]);
catch (ArrayIndexOutOfBoundsException e)
e.printStackTrace();
System.out.println("捕捉到了一个数组越界异常!");
System.out.println("我是异常代码的后续代码,我被执行了!");
2.1.2捕获多种异常
Java异常机制支持多种异常的捕获,最常用的方法,就是使用多个catch语句,捕捉多个异常的具体类型。
一个try…catch语句,catch语句可以存在多个:
public class Test4
public static void main(String[] args)
try
//可能出现异常的代码段
catch (异常类 异常变量名)
//处理该异常
catch (...)
//处理
...
而对于try语句中的代码段,当代码段中遇到异常时,发生异常的后面的所有代码段将不再执行,会直接执行对应catch中的语句。
比如,我将三句都有异常的代码写在同一个try语句中,使用多个catch语句捕捉这三种类型的异常,实际上只会捕捉到第一个异常。
public class Test7
public static void main(String[] args)
int a = 0;
int[] arr = new int[10];
String str = null;
try
System.out.println(8 / a);
System.out.println(arr[20]);
System.out.println(str.equals("aaa"));
catch (ArithmeticException e)
e.printStackTrace();
System.out.println("捕捉到了除数为0异常!");
catch (ArrayIndexOutOfBoundsException e)
e.printStackTrace();
System.out.println("捕捉到了一个数组越界异常!");
catch (NullPointerException e)
e.printStackTrace();
System.out.println("捕捉到了一个空指针异常!");
try语句中第一个异常语句为除数为0而引发的算术异常,所以最终捕捉的异常只有算术异常。
如果第一个语句没有异常,则捕捉的是后面第一个发生异常语句的异常,也就是说一个try语句只能捕获一个异常。
public class Test7
public static void main(String[] args)
int a = 2;
int[] arr = new int[10];
String str = null;
try
System.out.println(8 / a);
System.out.println(arr[20]);
System.out.println(str.equals("aaa"));
catch (ArithmeticException e)
e.printStackTrace();
System.out.println("捕捉到了除数为0异常!");
catch (ArrayIndexOutOfBoundsException e)
e.printStackTrace();
System.out.println("捕捉到了一个数组越界异常!");
catch (NullPointerException e)
e.printStackTrace();
System.out.println("捕捉到了一个空指针异常!");
除了使用多个catch语句,还可以使用|
分隔符在一个catch语句中定义多种类型的异常类:
public class Test8
public static void main(String[] args)
int[] arr = new int[10];
String str = null;
try
System.out.println(2/0);
catch (ArrayIndexOutOfBoundsException | NullPointerException | ArithmeticException e)
e.printStackTrace();
System.out.println("捕捉到了一个除数为0异常或数组越界异常或空指针异常!");
public class Test8
public static void main(String[] args)
int[] arr = new int[10];
String str = null;
try
System.out.println(arr[20]);
System.out.println(str.equals("aaa"));
catch (ArrayIndexOutOfBoundsException | NullPointerException | ArithmeticException e)
eJava异常处理机制