如何优雅的打印异常信息

由不能使用e.printStackTrace();的规范引起的思考

背景

在代码规范中,有着不要使用e.printStackTrace(),请使用logger记录的规范

为什么会有这样一条呢?因为e.printStackTrace() 会导致锁死!!!

e.printStackTrace() 语句要产生的字符串记录的是堆栈信息

这就会产生下面一种情况:

短时间内大量请求访问此接口 -> 代码本身有问题,很多情况下抛异常 -> e.printStackTrace() 来打印异常到控制台 -> 产生错误堆栈字符串到字符串池内存空间 -> 此内存空间一下子被占满了 -> 开始在此内存空间产出字符串的线程还没完全生产完整,就没空间了 -> 大量线程产出字符串产出到一半,等在这儿(等有内存了继续搞啊)-> 相互等待,等内存,锁死了,整个应用挂掉了。

综上,这就是 e.printStackTrace() 引发的血案。

代替

使用logger来代替记录

但是logger来代替,又有几种方式

logger.error(e.getMessage());
logger.error("发生了错误:"+e);
logger.error("发生了错误:",e);

这三种方式有什么区别呢?

logger.error(e.getMessage());

打印的只有异常的错误信息,如果异常没有抛出错误信息,则显示的就是null

logger.error(“发生了错误:”+e);

打印的是异常的类和异常的错误信息,这个也只比上面多了一个异常的类名

logger.error(“发生了错误:”,e);

推荐使用这种,会完整的将e打印出来

上案列

 public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(Test01.class);
        try {
            User user = null;
            user.setUserName("aaa");
        }catch (Exception e){
            logger.error(e.getMessage());
            logger.error("发生了错误:"+e);
            logger.error("发生了错误:",e);
        }
    }

测试结果

15:23:29.528 [main] ERROR com.qing.security.sys.Test01 - null
15:23:29.530 [main] ERROR com.qing.security.sys.Test01 - 发生了错误:java.lang.NullPointerException
15:23:29.532 [main] ERROR com.qing.security.sys.Test01 - 发生了错误:
java.lang.NullPointerException: null
	at com.qing.security.sys.Test01.main(Test01.java:13)

可以明显看出三者的区别,因此,如果需要完整的显示异常信息推荐使用 logger.error(“发生了错误:”,e);

下面在测试一个抛出了异常信息的例子

 public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(Test01.class);
        try {
            throw new Exception("我是个错误的代码");
        }catch (Exception e){
            logger.error(e.getMessage());
            logger.error("发生了错误:"+e);
            logger.error("发生了错误:",e);
        }
    }

测试结果:

15:25:03.178 [main] ERROR com.qing.security.sys.Test01 - 我是个错误的代码
15:25:03.182 [main] ERROR com.qing.security.sys.Test01 - 发生了错误:java.lang.Exception: 我是个错误的代码
15:25:03.183 [main] ERROR com.qing.security.sys.Test01 - 发生了错误:
java.lang.Exception: 我是个错误的代码
	at com.qing.security.sys.Test01.main(Test01.java:11)

最终推荐

如果只是想查看显示的异常信息,使用 logger.error(e.getMessage());

如果想查看完整的异常,请使用 logger.error(“发生了错误:”,e);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 的异常处理机制可以说非常重要,它能够帮助我们优雅地处理程序中的异常情况。以下是一些关于如何在 Java 中实现优雅异常处理的建议: 1. 使用适当的异常类型:Java 提供了许多内置的异常类型,你应该根据具体情况选择合适的异常类型。这样可以让代码更具可读性,并且方便其他开发人员理解你的代码。 2. 不要捕获所有异常:捕获异常意味着你要对其进行处理,但并不是所有的异常都需要你来处理。只捕获那些你能够处理或者你有必要处理的异常,对于其他异常,可以通过在方法签名中声明 throws 关键字来传递给上层调用者处理。 3. 使用 try-with-resources:对于实现了 AutoCloseable 接口的资源对象,可以使用 try-with-resources 语句来自动关闭资源。这样可以避免资源泄漏,并且能够更好地管理资源。 4. 使用自定义异常:除了使用内置的异常类型,你还可以根据具体需求创建自定义异常。自定义异常可以提供更加具体的异常信息,帮助你更好地定位问题。 5. 记录和处理异常信息:在捕获到异常时,不仅仅是简单地打印异常堆栈信息,你还应该考虑记录异常信息,并根据具体情况进行适当的处理。可以将异常信息写入日志文件,或者返回给用户友好的错误提示。 6. 避免空指针异常:空指针异常是 Java 开发中最常见的异常之一。为了避免空指针异常,你可以使用 null 检查、空对象模式、Optional 类型等方式来处理可能为 null 的对象。 7. 分层处理异常:在程序中可以使用多层的异常处理机制,将底层的异常转换为更高级别的异常,从而能够更好地管理和处理异常。 总之,优雅异常处理需要根据具体情况进行合理选择和实践。通过合适的异常类型、适当的捕获和处理、记录和传递异常信息,以及避免常见的错误,你能够使你的代码更加健壮和可维护。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值