在 toString 实现中捕获泛型异常 - 不好的做法?



我有一个域模型类,它有一个看起来像这样的toString实现:

public String toString() {
try {
return getX() + "n"
getY() + "n"
getZ(); //etc.
} catch(Exception e) {
throw new RuntimeException(e);
}
}

方法getX()getY()getZ()不是简单的getter,它们可以在后台执行查找,通常是对预定义键值对的静态映射的查找。他们中的一些人的签名中有throws SomeCheckedException

我的印象是,这是不好的做法和"代码气味"。事实上,toString()甚至需要这个检查对我来说是糟糕设计的症状。但是一位同事问我,在toString()中捕获通用Exception到底有什么问题,因为捕获的Exception会进一步传播。

我相信它至少违反了 KISS 原则,因为像这里toString()这样的简单方法被指示为需要特殊的异常处理。

那么在 toString() 中有一个包罗万象块是代码异味吗?

我找到的答案要么是针对捕获泛型Exception的一般场景,我同意其中的大多数,即如果您正在执行通用错误处理机制或批处理,那么它应该适用于通用异常。这个论点在我们的讨论中没有说服力,所以我对其他观点很好奇。

对于toString()方法,捕获Exception不一定是不好的做法。但是,重新扔掉它是有问题的部分。

toString() 的合约是:

。 通常,toString 方法返回一个"文本表示"此对象的字符串。结果应该是一个简洁但信息丰富的表示,一个人很容易阅读......

在Effective Java 3rd Edition(第12项)中,Bloch进一步坚持:

如果可行,toString 方法应返回对象中包含的所有有趣信息。

因此,如果这需要调用可能引发检查异常的方法,那就这样吧,捕获这些异常很有意义。

但是:引发的检查异常提供有关对象状态的信息。与toString的目标一致,在toString返回的消息中包含异常条件可能是一个好主意。

至于为什么从toString中抛出异常是个坏主意,这篇文章提供了一个很好的答案。

建议:使用选中的异常类型捕获其特定异常类型,并将此事实集成到toString()消息中,而不是传播它。

是的,这是不好的做法。

toString 方法的目的是为程序员提供类的可读表示形式。不应在此方法中包含任何方法调用,包括 getter。

事实上,我会考虑不要自动生成这些方法很臭,但假设你不舒服或无法使用可以为你生成它们的IDE,我建议包括对对象上所有字段的引用,以及对象的类名,就像intellij toString方法所做的那样。

不在任何地方捕获泛型异常的主要原因是它也将包括运行时异常,这在正常情况下不应该被捕获,因为它们总是代表程序中的错误。最好让它们传播和出现,以便开发人员可以注意到它并最终修复它。

我不知道在toString方法的情况下是否应该应用任何额外的良好实践检查,但我相信至少应该应用一般规则。

因此,最佳做法始终是仅捕获已检查的异常,然后恢复、重新抛出它们,或者将它们重新包装到另一个异常中(这是您的情况)。

"正常流程"应该被失败的 toString() 方法中断吗?如果答案是否定的,你应该让 toString() 方法"工作"。捕获异常并在结果中反映这一点是一种可能性,或者简单的日志输出。

最新更新