异常
Java语言中,将程序执行发生不正常情况称为”异常“
开发过程中的语法错误和逻辑错误不是异常
执行过程中的异常可以分为两类
-
Error(错误):Java虚拟机无法解决的严重问题。如:JVM系统内部错误,资源耗尽等严重情况,eg.StackOverflowError(栈溢出)。Error是严重错误,程序会崩溃
-
Exception :其他编程错误或偶然的外在因素导致的一般性错误,可以使用针对性代码进行处理。例如空指针访问,网络连接中断等。
Exception又可以分为运行时异常和编译时异常编译时异常,编译器一般可以检测出来,会报错,例如类没找到;而运行时异常编译器无法检测
编译时异常必须处理;运行时异常可以不做处理,因为比较普遍,如果都处理,回会影响代码的可读性和效率
异常体系结构图
异常的处理方式
try-catch-finally
程序员捕获程序中的异常,自行处理
int num1=1;
int num2=0;
int res=num1/num2;
System.out.println("程序继续执行");
执行这段代码,就会抛出下面的异常。程序不会继续执行
我们可以用try-catch包裹可能发生异常的代码
try {
//这段代码可能有异常
int num1=1;
int num2=0;
int res=num1/num2;
}catch (NullPointerException e){
System.out.println("空指针异常:"+e.getMessage());
}catch (ArithmeticException e){
System.out.println("算数异常:"+e.getMessage());
} catch (Exception e) {
//捕获异常,处理异常
e.printStackTrace();
System.out.println(e.getMessage());//输出异常信息
}finally {
//无论,是否发生异常都会执行
//通常用作资源的释放
System.out.println("finally");
}
System.out.println("程序继续执行");
异常信息打印之后,程序会继续执行
throws
如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
在方法声明中用 throws语句可以声明抛出异常的列表, throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类
public void fun1() throws FileNotFoundException {
FileInputStream fileInputStream = new FileInputStream("D://a.txt");
}
如果自己不try-catch,就会有一个默认的throws Exception
最顶级的处理者就是JVM,JVM的处理方式:输出异常信息,退出程序
子类重写父类方法时,抛出的异常和父类抛出异常一致或是其子类
自定义异常
自定义一个类继承Exception或RuntimeException
继承Exception是编译时异常;
继承RuntimeException是运行时异常,一般继承这个
public class Ex1 {
public static void main(String[] args) {
int age=-1;
if(age>=0&&age<100){
System.out.println("年龄符合");
}else{
throw new AgeException("年龄不符合");
}
}
}
class AgeException extends RuntimeException{
public AgeException(String message){
super(message);
}
}
throw和throws比较
Springboot
参考资料
- 官方:https://docs.spring.io/spring-boot/docs/2.7.8/reference/html/web.html#web.servlet.spring-mvc.error-handling
- 中文:https://springdoc.cn/spring-boot/web.html#web.servlet.spring-mvc.error-handling
- 视频:https://www.bilibili.com/video/BV19K4y1L7MT?p=52&spm_id_from=pageDriver&vd_source=1fe29350b37642fa583f709b9ae44b35
- 笔记:https://www.yuque.com/atguigu/springboot/vgzmgh#6ezTG
当请求路径不存在或者发生错误异常的时候,默认情况下,springboot提供 /error
的映射
-
对于浏览器客户端,会出现如下页面
-
对于非浏览器客户端,例如postman等,会返回一个json字符串
{ "timestamp": "2023-02-01T09:50:38.933+00:00", "status": 500, "error": "Internal Server Error", "path": "/test" }
自定义
自定义error页面
前后端不分离项目
如果你想为一个给定的状态代码显示一个自定义的HTML错误页面,你可以在 /error 目录下添加一个文件。 错误页面可以是静态HTML(即添加在任何一个静态资源目录下),也可以通过使用模板建立。 文件的名称应该是准确的状态代码或一系列的掩码。
例如,要把 404 映射到一个静态HTML文件,你的目录结构如下。
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
如果使用模板引擎的话,例如通过使用FreeMarker模板来映射所有 5xx 错误,你的目录结构如下。
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftlh
+- <other templates>
自定义异常处理
@ControllerAdvice和@ExceptionHandler(MyException.class)搭配使用
@ControllerAdvice
public class MyExceptionController {
@ExceptionHandler(MyException.class)
public void handlerRuntimeException(MyException e){
System.out.println("全局异常处理"+e.getMessage());
}
}