Java自定义异常输出

要理解Java异常处理是如何工作的,你需要掌握以下三种类型的异常:

  • 检查性异常:
    最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  • 运行时异常:
    运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误:
    错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

一.Exception 类的层次

在这里插入图片描述

从继承关系可知:Throwable是异常体系的根,它继承自Object。Throwable有两个体系:Error和Exception,Error表示严重的错误,程序对此一般无能为力,例如:
1.OutOfMemoryError:内存耗尽
2.NoClassDefFoundError:无法加载某个Class
3.StackOverflowError:栈溢出

而Exception则是运行时的错误,它可以被捕获并处理。某些异常是应用程序逻辑处理的一部分,应该捕获并处理。例如:
1.NumberFormatException:数值类型的格式错误
2.FileNotFoundException:未找到文件
3.SocketException:读取网络失败
还有一些异常是程序逻辑编写不对造成的,应该修复程序本身。例如:
1.NullPointerException:对某个null的对象调用方法或字段
2.IndexOutOfBoundsException:数组索引越界
Exception又分为两大类:
1.RuntimeException以及它的子类;
2.非RuntimeException(包括IOExceptionReflectiveOperationException等等)
Java规定:
必须捕获的异常,包括Exception及其子类,但不包括RuntimeException及其子类,这种类型的异常称为Checked Exception。

不需要捕获的异常,包括Error及其子类,RuntimeException及其子类。

二.捕获异常

捕获异常使用try…catch语句,把可能发生异常的代码放到try {…}中,然后使用catch捕获对应的Exception及其子类

 try {
   Integer.valueOf("22m");
 } catch (NumberFormatException e) {
   e.printStackTrace();
 }

在异常捕获的同时,我们希望同时输出异常的详细信息,大多数情况下会选择e.printStackTrace(); 这个方法,但是他对于系统 的性能会有一定的影响,先不说开销的问题,有些时候我们需要做一些自定义的输出,与log系统进行结合,可是e.printStackTrace(); 并没有返回值,这就很尴尬,接下来我们自定义异常收集器

三.自定义异常收集器

3.1 定义log输出的模板

设计的理念:
1.我们采用模板的设计模式定义接口,如果小伙伴对模板模式不了接,请看这篇文章https://blog.csdn.net/weixin_38937840/article/details/104211816
2.我们获取堆里的异常信息(当然获取Throwable ,Exception也是可以),源码在文末会提供

public abstract class LogTemplate {
    /**前缀*/
    protected static final String PREFIX = "Java有货";
    /**链接符*/
    protected static final String JOINER = "-----";

    /**
     * <p>
     *       自定义前缀输出
     * </p>
     * /
    protected abstract void logError(String prefix,StackTraceElement[] stackTrace);

    /**
     * <p>
     *       默认前缀统一输出
     * </p>
     */
    protected abstract void logError(StackTraceElement[] stackTrace);

//    protected abstract void logError(String prefix, Exception e);
//    protected abstract void logError(Exception e);
//    protected abstract void logError(String prefix, Throwable e);
//    protected abstract void logError(Throwable e);


    protected boolean verify(String prefix){
        boolean blank = StringUtils.isEmpty(prefix);
        return blank;
    }

    /**
     *       统一日志出口
     */
    public void logPrint(String prefix, StackTraceElement[] stackTrace){
        boolean verify = verify(prefix);
        if (verify){
            logError(stackTrace);
        }else {
            logError(prefix,stackTrace);
        }
    }
3.2 实现自定义输出
@Slf4j
public class LogError extends LogTemplate {
    @Autowired(required = false)
    private TaskExecutor taskExecutor;
    private static final String MSG = " 错误详细信息 : ";
    /**
     * <p>
     *       错误日志记录
     * </p>
     */
    @Override
    protected void logError(String prefix,StackTraceElement[] stackTrace) {
        log(prefix ,stackTrace );
    }

    /**
     * <p>
     *       错误日志记录
     * </p>
     */
    @Override
    protected void logError(StackTraceElement[] stackTrace) {
        log(stackTrace);
    }


    /**
     * <p>
     *       错误日志记录,内部输出
     * </p>
     */
    private void log(String prefix,StackTraceElement[] stackTrace){
        CompletableFuture.runAsync(() -> {
            for (StackTraceElement stackTraceElement : stackTrace) {
                log.error(PREFIX + JOINER + prefix.trim() + JOINER + "{}",MSG+ stackTraceElement.toString());
            }
        },taskExecutor);

    }

    /**
     * <p>
     *       错误日志记录,内部输出
     * </p>
     */
    private void log(StackTraceElement[] stackTrace){
        CompletableFuture.runAsync(() -> {
            for (StackTraceElement stackTraceElement : stackTrace) {
                log.error(PREFIX  + "{}", JOINER +MSG+ stackTraceElement);
            }
        },taskExecutor);
    }
}

这里使用了CompletableFuture,如果不了解的同学,请看下面的文章
https://blog.csdn.net/weixin_38937840/article/details/105046588

3.3 使用验证
 try {
   Integer.valueOf("22m");
 } catch (NumberFormatException e) {
   logError.logPrint("swagger",e.getStackTrace());
 }

如下图,这时我们就可以与业务场景进行高度结合,快速定位
在这里插入图片描述
源码地址:https://github.com/Dylan-haiji/javayh-platform/tree/master/javayh-starter/javayh-log-starter/src/main/java/com/javayh/log/log
本文的分享暂时就到这里,希望对您有所帮助
关注 Java有货领取更多资料

联系小编。微信:372787553,带您进群互相学习
左侧小编微信,右侧获取免费资料
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小杨同学~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值