会员登录 - 用户注册 - 设为首页 - 加入收藏 - 网站地图 怎么高雅的处理反常 Java言语反常剖析!

怎么高雅的处理反常 Java言语反常剖析

时间:2025-05-21 04:32:28 来源:锐评时讯 作者:经济 阅读:686次

一、什么是反常。

Java。言语依照过错严重性,从 throwale 根类衍生出 Error 和 Exception 两大派系。

Error(过错):

程序在履行进程中所遇到的。硬件。或。操作体系。的过错。过错对程序而言是丧命的,将导致程序无法运转。常见的过错有内存溢出,jvm 虚拟机本身的非正常运转,calss 文件没有主办法。程序本生是不能处理过错的,只能依托外界干涉。Error 是体系内部的过错,由 jvm 抛出,交给体系来处理。

Exception(反常):

程序正常运转中,能够意料的意外状况。比方数据库衔接中止,空指针,数组下标越界。反常呈现能够导致程序非正常停止,也能够预先。检测。,被捕获处理掉,使程序持续运转。Exception(反常)依照性质,又分为编译反常(受检反常)和运转时反常(非受检反常)。

◦编译反常:

又名可查看反常,一般时由语法错和环境要素(外部资源)形成的反常。比方输入输出反常 IOException,数据库操作 SQLException。其特点是,Java 言语强制要求捕获和处理一切非运转时反常。经过行为规范,强化程序的健壮性和安全性。

◦运转时反常:

又名不查看反常 Run。ti。meException,这些反常一般是由程序逻辑过错引起的,即语义错。比方算术反常,空指针反常 NullPointerException,下标越界 IndexOutOfBoundsException。运转时反常应该在程序测验期间被露出出来,由。程序员。去调试,而防止捕获。

二、处理反常方法。

代码中,咱们最常见到的处理反常的方法便是:try-catch。

try {            // 事务逻辑                    } catch (Exception e) {            // 捕获到反常的逻辑        }。

或者是再进一步区别下反常类型:

try {            // 事务逻辑                    } catch (IOException ie) {            // 捕获到IO反常的逻辑                    } catch (Exception e) {            // 捕获到其他反常的逻辑        }。

三、怎么抛出反常。

咱们一般能够用抛出反常的方法来操控代码流程,然后在网关处一致catch反常来回来过错code。这在必定程度上能够简化代码流程操控,如下所示:

Override    publ。ic。UserVO queryUser(Long id) {        UserDO userDO = userMapper.queryUserById(id);        if (Objects.isNull(userDO)) {            throw new RuntimeException("用户不存在");    //用户不存在抛出反常        }        return userDO.toVo();    }。  

上面这种抛出反常的方法,尽管简化了代码流程,可是在存在多种过错场景时,没有办法细分详细的过错类型。如:用户不存在的过错、用户没有权限的过错;

聪明如你,必定想到了自界说反常,如下:

Override    public UserVO queryUser(Long id) {        UserDO userDO = userMapper.queryUserById(id);        if (Objects.isNull(userDO)) {            throw new UserNo。tF。oundException();    //用户不存在抛出对应反常        }        if(!checkLicence(userDO)) {            throw new B。ad。LicenceException();    //用户无权限抛出对应反常        }        return userDO.toVo();    }。

的确,自界说反常能够处理过错场景细分的问题。进一步的,咱们能够对体系流程不同阶段、不同事务类型别离自界说反常,但这需求自界说很多的反常;

四、怎么高雅的抛出反常。

上面的方法,能够区别出过错场景了,可是还存在一些缺陷。如:可读性差、需求界说很多的自界说反常;

那咱们下面就去优化上面的问题;

用断语添加代码的可读性;

Override    public UserVO queryUser(Long id) {        UserDO userDO = userMapper.queryUserById(id);        Assert.notNull(userDO, "用户不存在");    //用断语进行。参数。的非空校验        return userDO.toVo();    }。

断语尽管代码简练、可读性好,可是缺少像上述自界说反常相同能够清晰区别过错场景,这就引出咱们的究极计划:自界说断语;

自界说断语;

咱们用自界说断语的方法,归纳上面自界说反常和断语的长处,在断语失利后,抛出咱们制定好的反常。代码如下:

•自界说反常根本类。

Get。te。rSetterpublic class BaseException extends RuntimeException {    // 呼应码    private IResponseEnum responseEnum;    // 参数。信息。private Object[] objs;    public BaseException(String message, IResponseEnum responseEnum, Object[] objs) {        super(message);        this.responseEnum = responseEnum;        this.objs = objs;    }    public BaseException(String message, Throwable cause, IResponseEnum responseEnum, Object[] objs) {        super(message, cause);        this.responseEnum = responseEnum;        this.objs = objs;    }}。

•自界说断语。接口。

public interface MyAssert {    /**     * 创立自界说反常     *     * pa。ram。objs 参数信息     * return 自界说反常     */    BaseException newException(Object... objs);    /**     * 创立自界说反常     *     * param msg  描绘信息     * param objs 参数信息     * return 自界说反常     */    BaseException newException(String msg, Object... objs);    /**     * 创立自界说反常     *     * param t    接纳验证反常     * param msg  描绘信息     * param objs 参数信息     * return 自界说反常     */    BaseException newException(Throwable t, String msg, Object... objs);    /**     * 校验非空     *     * param obj 被验证目标     */    default void assertNotNull(Object obj, Object... objs) {        if (obj == null) {            throw newException(objs);        }    }    /**     * 校验非空     *     * param obj 被验证目标     */    default void assertNotNull(Object obj, String msg, Object... objs) {        if (obj == null) {            throw newException(msg, objs);        }    }}。

上述代码咱们能够看出根本规划,便是在咱们自界说断语失利后抛出咱们自界说反常。

下面是详细的完成事例:

•自界说事务反常类,承继自反常根本类。

public class BusinessException extends BaseException {    public BusinessException(IResponseEnum responseEnum, Object[] args, String msg) {        super(msg, responseEnum, args);    }    public BusinessException(IResponseEnum responseEnum, Object[] args, String msg, Throwable t) {        super(msg, t, responseEnum, args);    }}。

•呼应code枚举接口界说。

public interface IResponseEnum {    /**     * 回来code码     *     * return code码     */    String getCode();    /**     * 回来描绘信息     *     * return 描绘信息     */    String getMsg();}。

•自界说事务反常类断语界说,完成自界说断语失利后对应的自界说反常的界说;

public interface BusinessExceptio。nAs。sert extends IResponseEnum, MyAssert {    Override    default BaseException newException(Object... args) {        return new BusinessException(this, args, this.getMsg());    //断语失利后,抛出自界说反常    }    Override    default BaseException newException(String msg, Object... args) {        return new BusinessException(this, args, msg);              //断语失利后,抛出自界说反常    }    Override    default BaseException newException(Throwable t, String msg, Object... args) {        return new BusinessException(this, args, msg, t);           //断语失利后,抛出自界说反常    }}。

•用枚举的方法,替代BadLicenceException、UserNotFoundException自界说反常。

public enum ResponseEnum implements IResponseEnum, BusinessExceptionAssert {    BAD_LICENCE("0001", "无权拜访"),    USER_NOT_FOUND("1001", "用户不存在"),    ;    private final String code, msg;    ResponseEnum(String code, String msg) {        this.code = code;        this.msg = msg;    }    Override    public String getCode() {        return code;    }    Override    public String getMsg() {        return msg;    }}。

运用实例。

自界说断语失利抛出自界说反常。

Override    public UserVO queryUser(Long id) {        UserDO userDO = userMapper.queryUserById(id);        ResponseEnum.USER_NOT_FOUND.assertNotNull(userDO);    //自界说断语失利抛出自界说反常        return userDO.toVo();    }。

网关处一致catch反常,辨认反常场景。

public static void main(String[] args) {        Use。rS。ervice userService = new UserServiceImpl(new UserMapperImpl());        UserController userController = new UserController(userService);        try {            UserVO vo = userController.queryUser(2L);               //履行事务逻辑        } catch (BusinessException e) {            System.out.println(e.getResponseEnum().getCode());      //呈现反常,过错code:1001            System.out.println(e.getMessage());                     //呈现反常,过错msg:用户不存在        }    }。

五、怎么高雅的处理反常。

网关处一致处理反常,这归于惯例操作,这儿不再赘述,简略举例如下:

ControllerA。dvi。cepublic class BusinessExceptionHandler {        ExceptionHandler(value = BusinessException.class)    ResponseBody    public Response handBusinessException(BaseException e) {        return new Response(e.getResponseEnum().getCode(), e.getResponseEnum().getMsg());    //一致处理反常    }}。

综上,咱们选用自界说断语的方法,结合了断语的可读性高的优势和自界说反常区别过错场景的优势。而且,有新增的过错场景,咱们只需求在过错码枚举中新增对应枚举即可。

审阅修改 黄宇。

内容来源:https://artdesignphuong.com/app-1/banh số 4,http://chatbotjud-teste.saude.mg.gov.br/app-1/bet-365-levantamento-banco-do-brasil

(责任编辑:人文)

    系统发生错误

    系统发生错误

    您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ]

    [ 错误信息 ]

    页面发生异常错误,系统设置开启调试模式后,刷新本页查看具体错误!