2023年11月29日发(作者:)
Java基础知识(四)exception异常处理
检查性异常:最具代表的检查性异常是⽤户错误或问题引起的异常,这是程序员⽆法预见的。例如要打开⼀个不存在⽂件时,⼀个异常就发⽣
了,这些异常在编译时不能被简单地忽略。
运⾏时异常: 运⾏时异常是可能被程序员避免的异常。与检查性异常相反,运⾏时异常可以在编译时被忽略。
错误: 错误不是异常,⽽是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,⼀个错误就发⽣了,它们在编译也检查不
到的。
所有的异常类是从 ion 类继承的⼦类。Exception 类是 Throwable 类的⼦类。除了Exception类外,Throwable还有⼀个⼦
类Error 。
Java 程序通常不捕获错误。错误⼀般发⽣在严重故障时,它们在Java程序处理的范畴之外。
Error ⽤来指⽰运⾏时环境发⽣的错误。
例如,JVM 内存溢出。⼀般地,程序不会从错误中恢复。
异常类有两个主要的⼦类:IOException 类和 RuntimeException 类。
我们所谓的异常处理,基本是指IOException , RuntimeException 和⾃定义异常处理
⾮检查性异常
异常描述
ArithmeticException当出现异常的运算条件时,抛出此异常。例如,⼀个整数"除以零"时,抛出此类的⼀个实例。
ArrayIndexOutOfBounds⽤⾮法索引访问数组时抛出的异常。如果索引为负或⼤于等于数组⼤⼩,则该索引为⾮法索
Exception引。
ArrayStoreException试图将错误类型的对象存储到⼀个对象数组时抛出的异常。
IllegalArgumentExceptio
异常描述
n
IllegalMonitorStateExcep抛出的异常表明某⼀线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视
tion器⽽本⾝没有指定监视器的线程。
IllegalStateException
IllegalThreadStateExcept
ion
IndexOutOfBoundsExce
ption
NegativeArraySizeExcep
tion
NullPointerException
NumberFormatExceptio当应⽤程序试图将字符串转换成⼀种数值类型,但该字符串不能转换为适当格式时,抛出该异
n常。
SecurityException由安全管理器抛出的异常,指⽰存在安全侵犯。
StringIndexOutOfBound
sException
UnsupportedOperationE
xception
抛出的异常表明向⽅法传递了⼀个不合法或不正确的参数。
在⾮法或不适当的时间调⽤⽅法时产⽣的信号。换句话说,即 Java 环境或 Java 应⽤程序没有
处于请求操作所要求的适当状态下。
3public String toString() 使⽤getMessage()的结果返回类的串级名字。
序
号
4public void printStackTrace() 打印toString()结果和栈层次到,即错误输出流。
5
⽅法及说明
public StackTraceElement [] getStackTrace() 返回⼀个包含堆栈层次的数组。下标为0的元素代表栈顶,最后⼀个
元素代表⽅法调⽤堆栈的栈底。
public Throwable fillInStackTrace() ⽤当前的调⽤栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息
中。
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
如何定义⼀个全局异常处理类
1.先定义异常枚举类
public enum ErrorEnum {
/**
* 成功
*/
SUCCESS("1", 1, "SUCCESS", "成功"),
/**
* 失败
*/
FAILED("-1", -1, "FAILED", "失败"),
//---------------- ⼀般错误(0001-0999) ----------------
/**
* 未知错误
private ErrorEnum error;
/**
* 错误详情
*/
private String detail;
/**
/**
* @ControllerAdvice 捕获 Controller 层抛出的异常,如果添加 @ResponseBody 返回信息则为JSON格式。
* @RestControllerAdvice 相当于 @ControllerAdvice 与 @ResponseBody 的结合体。
* @ExceptionHandler 统⼀处理⼀种类的异常,减少代码重复率,降低复杂度。
*/
@RestControllerAdvice
public class GlobalDefaultExceptionHandler extends BaseController {
/**
* 拦截⾃定义错误信息
*
* @param exception CommonException
* @return 错误信息
*/
@ExceptionHandler(value = )
@ResponseStatus()
public Map
return returnResultMap(L, sage());
}
/**
* 拦截NoHandlerFoundException
* 拦截controller对应的mapping 路径找到,即平时所说的 404
* @param exception NoHandlerFoundException
* @return 错误信息
* 如何想 404 ⽣效,必须进⾏下⾯俩⾏配置
* -exception-if-no-handler-found=true
* -mappings=false
*
*/
@ExceptionHandler(value = )
@ResponseStatus(_FOUND)
但是配置上⾯俩⾏之后,项⽬下⾯的静态资源也全部⽆法访问,如果是前后端分离那⽆所谓,如果是使⽤了java模板⽂件,需进⾏对应的下⾯配置
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
ourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
常见⾯试题
1.Error 和 Exception 区别是什么?
Error 类型的错误通常为虚拟机相关错误,如系统崩溃,内存不⾜,堆栈溢出等,编译器不会对这类错误进⾏检测,JAVA 应⽤程序也不应对这
类错误进⾏捕获,⼀旦这类错误发⽣,通常应⽤程序会被终⽌,仅靠应⽤程序本⾝⽆法恢复;
Exception 类的错误是可以在应⽤程序中进⾏捕获并处理的,通常遇到这种错误,应对其进⾏处理,使应⽤程序可以继续正常运⾏。
是如何处理异常的?
在⼀个⽅法中如果发⽣异常,这个⽅法会创建⼀个异常对象,并转交给 JVM,该异常对象包含异常名称,异常描述以及异常发⽣时应⽤程序的状
态。创建异常对象并转交给 JVM 的过程称为抛出异常。可能有⼀系列的⽅法调⽤,最终才进⼊抛出异常的⽅法,这⼀系列⽅法调⽤的有序列表叫
做调⽤栈。
JVM 会顺着调⽤栈去查找看是否有可以处理异常的代码,如果有,则调⽤异常处理代码。当 JVM 发现可以处理异常的代码时,会把发⽣的异常
传递给它。如果 JVM 没有找到可以处理该异常的代码块,JVM 就会将该异常转交给默认的异常处理器(默认处理器为 JVM 的⼀部分),默认
异常处理器打印出异常信息并终⽌应⽤程序。
ow 和 throws 的区别是什么?
throw 语句⽤在⽅法体内,表⽰抛出异常,由⽅法体内的语句处理。
throw 是具体向外抛出异常的动作,所以它抛出的是⼀个异常实例,执⾏ throw ⼀定是抛出了某种异常。
throws 语句是⽤在⽅法声明后⾯,表⽰如果抛出异常,由该⽅法的调⽤者来进⾏异常的处理。
throws 主要是声明这个⽅法会抛出某种类型的异常,让它的使⽤者要知道需要捕获的异常的类型。
throws 表⽰出现异常的⼀种可能性,并不⼀定会发⽣这种异常。
4.final、finally、finalize的区别?
final:⽤于声明属性,⽅法和类,分别表⽰属性不可变,⽅法不可覆盖,被其修饰的类不可继承。
finally:异常处理语句结构的⼀部分,表⽰总是执⾏。
finalize:Object 类的⼀个⽅法,在垃圾回收器执⾏的时候会调⽤被回收对象的此⽅法,可以覆盖此⽅法提供垃圾收集时的其他资源回收,例
如关闭⽂件等。该⽅法更像是⼀个对象⽣命周期的临终⽅法,当该⽅法被系统调⽤则代表该对象即将"死亡",但是需要注意的是,我们主动⾏
为上去调⽤该⽅法并不会导致该对象"死亡",这是⼀个被动的⽅法(其实就是回调⽅法),不需要我们调⽤。
lassDefFoundError 和 ClassNotFoundException 区别?
NoClassDefFoundError 是⼀个 Error 类型的异常,是由 JVM 引起的,不应该尝试捕获这个异常。引起该异常的原因是 JVM 或
ClassLoader 尝试加载某类时在内存中找不到该类的定义,该动作发⽣在运⾏期间,即编译时该类存在,但是在运⾏时却找不到了,可能是变
异后被删除了等原因导致;
ClassNotFoundException 是⼀个受查异常,需要显式地使⽤ try-catch 对其进⾏捕获和处理,或在⽅法签名中⽤ throws 关键字进⾏声
明。当使⽤ e, ass 或 stemClass 动态加载类到内存的时候,通过传⼊的类路径参
数没有找到该类,就会抛出该异常;另⼀种抛出该异常的可能原因是某个类已经由⼀个类加载器加载⾄内存中,另⼀个加载器⼜尝试去加载
它。
y-catch-finally 中哪个部分可以省略?
catch
更为严格的说法其实是:try只适合处理运⾏时异常,try+catch适合处理运⾏时异常+普通异常。也就是说,如果你只⽤try去处理普通异常却不
加以catch处理,编译是通不过的,因为编译器硬性规定,普通异常如果选择捕获,则必须⽤catch显⽰声明以便进⼀步处理。⽽运⾏时异常在编


发布评论