异常介绍
异常就是有异于常态,和正常情况不一样,有错误出现。在java中,阻止当前方法或作用域的情况,称之为异常。

异常分类

异常分类图

Exception具体实现

在系统开发中,平时经常需要使用的两种异常,一种是需要检查(checked)的,一种是不需要检查(unchecked)的。 那为什么需要两种异常呢?
  • 用来区分告警的优先级。系统异常优先级高,因为说明系统服务、代码存在问题。
    • 业务异常,是已知的,因为其他客观因素导致的,比如用户输入的身份证格式有问题、用户购买商品时金额不足等。
    • 系统异常,是未知的,不知道啥时候会发生,如果发生了说明系统本身或者系统上下游存在问题,需要立马告警出来,让相关开发者感知到;以便发现问题和后续优化问题。比如:系统上下游服务抖动、请求超时、请求参数存在问题等。
  • 使代码更清洁,该处理(checked)的异常内部处理掉,无法处理(unchecked)的异常告警出来。
往往对于开发者来说,比较难区分,何为系统系统,何为业务异常。其中系统异常是unchecked的,业务异常是checked。

RuntimeException

RuntimeException是在Java虚拟机的正常操作期间可以抛出的那些异常的超类,是Exception的子类,是Exception中unchecked子类的超类。 比如系统上下游抖动、请求超时等,是允许在系统运行期间抛出的,所以该类异常应该继承自RuntimeException;且无需检查(unchecked)。 所以系统异常应该继承自RuntimeException
开发时具体实现:
1
/**
2
* @Author : TommyYang
3
* @Time : 2021-03-27 12:40
4
* @Software: IntelliJ IDEA
5
* @File : SystemException.java
6
*/
7
public class SystemException extends RuntimeException {
8
9
private String code;
10
11
public SystemException(String code) {
12
this.code = code;
13
}
14
15
public SystemException(String message, String code) {
16
super(message);
17
this.code = code;
18
}
19
20
@Override
21
public String toString() {
22
return "SystemException{" +
23
"code='" + code + '\'' +
24
'}';
25
}
26
27
}
Copied!

Exception

异常类和任何不是RuntimeException的子类的子类都是检查异常。 检查的异常需要在方法或构造函数的throws子句中声明,如果它们可以通过执行方法或构造函数抛出,并在方法或构造函数边界之外传播。 比如用户输入的身份证格式有问题、用户购买商品时金额不足等,这些是在开发系统的时候,就会已经的会出现这样的问题,这类异常是应该内部处理(checked)掉,而不应该告警出来。 所以业务异常应该继承自Exception,且需要检查(checked)。
开发时具体实现:
1
/**
2
* @Author : TommyYang
3
* @Time : 2021-03-27 12:40
4
* @Software: IntelliJ IDEA
5
* @File : BusinessException.java
6
*/
7
public class BusinessException extends Exception {
8
9
private String code;
10
11
public BusinessException(String code) {
12
this.code = code;
13
}
14
15
public BusinessException(String message, String code) {
16
super(message);
17
this.code = code;
18
}
19
20
@Override
21
public String toString() {
22
return "BusinessException{" +
23
"code='" + code + '\'' +
24
'}';
25
}
26
}
Copied!

测试

1
/**
2
* @Author : TommyYang
3
* @Time : 2021-03-27 13:19
4
* @Software: IntelliJ IDEA
5
* @File : ExceptionTest.java
6
*/
7
public class ExceptionTest {
8
9
/**
10
* 测试checked异常
11
*/
12
@Test
13
public void testException() {
14
try {
15
throwsBusinessException();
16
} catch (BusinessException e) {
17
System.out.println("这是一个业务异常,内部处理掉" + e.toString());
18
}
19
}
20
21
/**
22
* 测试unchecked异常
23
*/
24
@Test
25
public void testRuntimeException() {
26
throwsSystemException();
27
}
28
29
/**
30
* 抛出业务异常(checked)
31
* 所以需要throw出去,让外部调用方感知到,这是一个checked的异常,是已经问题
32
*/
33
private void throwsBusinessException() throws BusinessException {
34
throw new BusinessException("403");
35
}
36
37
/**
38
* 抛出系统异常(unchecked)
39
*/
40
private void throwsSystemException() {
41
throw new SystemException("400");
42
}
43
44
}
Copied!

Error介绍

Error表示严重的问题,合理的应用程序不应该试图捕获。 大多数这样的错误是异常情况。 ThreadDeath错误虽然是“正常”的条件,但也是Error一个子类,因为大多数应用程序不应该试图抓住它。
Error是由虚拟机生成并抛出,大多数错误与代码开发者所执行的操作无关。 常见的Error,比如Java虚拟机运行错误(VirtualMachineError);当JVM执行操作所需的内存资源不够时,将出现OutOfMemoryError;当这些异常发生时,JVM一般会选择线程终止。 还有部分Error是发生在虚拟机试图执行应用时,比如类定义错误(NoClassDefFoundError)、链接错误(LinkageError);这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。 对于合理设计的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。 在Java中,错误通常是使用Error的子类描述。