java 报异常时候 printstacktrace 为什么不能用_java – 为什么exception.printStackTrace()被认为是不好的做法?...

本文探讨了使用Throwable.printStackTrace()方法进行异常处理的有效性和局限性。指出该方法在特定条件下可能不是一个理想的选择,尤其是在需要考虑日志轮换、多线程环境及日志文件解析的情况下。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Throwable.printStackTrace()将堆栈跟踪写入System.err PrintStream。 System.err流和JVM进程的底层标准“错误”输出流可以重定向

>调用System.setErr(),改变System.err指向的目的地。

>或通过重定向进程的错误输出流。错误输出流可以重定向到文件/设备

>其内容可能被人员忽视,

>文件/设备可能无法记录旋转,推断在归档文件/设备的现有内容之前需要进程重新启动以关闭打开的文件/设备句柄。

>或者文件/设备实际上丢弃写入它的所有数据,如/ dev / null的情况。

从上述推断,调用Throwable.printStackTrace()构成有效(不好/很好)异常处理行为,只有

>如果你没有在整个应用程序的生命周期重新分配System.err,

>如果在应用程序运行时不需要日志轮换,

>如果接受/设计的应用程序的日志实践是写入System.err(和JVM的标准错误输出流)。

在大多数情况下,不满足上述条件。可能不知道在JVM中运行的其他代码,并且不能预测日志文件的大小或进程的运行时间,而良好设计的日志实践将围绕编写“机器可解析”日志文件在记录器中的优选但可选的特征),以帮助支持。

最后,应该记住,Throwable.printStackTrace()的输出肯定会与写入System.err的其他内容(如果两者都重定向到同一文件/设备,甚至可能是System.out)交织。这是一个人必须处理的烦恼(对于单线程应用程序),因为异常的数据在这样的事件中不容易解析。更糟的是,多线程应用程序很可能会产生非常混乱的日志,因为Throwable.printStackTrace()不是线程安全的。

当多个线程同时调用Throwable.printStackTrace()时,没有同步机制来同步将堆栈跟踪写入System.err。解决此问题实际上需要您的代码在与System.err(以及System.out,如果目标文件/设备是相同的)相关联的监视器上同步,并且这是相当沉重的价格来支付日志文件的健全性。例如,ConsoleHandler和StreamHandler类负责将日志记录附加到控制台,在由java.util.logging提供的日志记录工具中;发布日志记录的实际操作是同步的 – 尝试发布日志记录的每个线程还必须获取与StreamHandler实例关联的监视器上的锁。如果希望使用System.out / System.err具有非交叉日志记录的同样保证,则必须确保相同 – 消息以可串行化的方式发布到这些流。

考虑到上述所有情况,以及Throwable.printStackTrace()实际上很有用的非常有限的情况,它经常证明调用它是一个坏的做法。

扩展前面段落中的参数,使用Throwable.printStackTrace与向控制台写入的记录器结合使用也是一个不好的选择。这部分是由于记录器在不同的监视器上同步的原因,而您的应用程序(可能,如果不想交叉日志记录)在不同的监视器上同步。当您在应用程序中使用两个不同的记录器写入相同的目标时,参数也是很好的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值