在toString实现中捕获通用异常-错误的做法?

时间:2019-06-21 16:21:30

标签: java exception tostring

我有一个域模型类,该类具有toString实现,如下所示:

#Store cookies
cookies = driver.get_cookies()
for cookie in cookies:
    with open('cookies.txt', 'a') as stored_cookies:
        stored_cookies.write(str(cookie) + '\n')

#Restore cookies
with open('cookies.txt') as stored_cookies:
    cookie = eval(stored_cookies.readline())
    driver.add_cookie(cookie)

方法public String toString() { try { return getX() + "\n" getY() + "\n" getZ(); //etc. } catch(Exception e) { throw new RuntimeException(e); } } getX()getY()不是简单的获取器,它们可以在后台执行查找,通常是对预定义键值对的静态映射进行查找。他们中有些人的签名上有getZ()

我的印象是,这是一种不好的做法,并且带有“代码气味”。 throws SomeCheckedException甚至需要检查的事实对我来说是不良设计的征兆。但是我的一个同事问,将通用toString()捕获到Exception中到底有什么问题,因为捕获的toString()会进一步传播。

我认为它至少违反了KISS原则,因为此处表示一种简单的方法,如Exception表示需要特殊的异常处理。

那么在toString()中包含一个包罗万象的块是否有代码味道?

我发现的答案或者是用于捕获通用toString()的一般情况,而我大多数都同意,如果您正在执行通用错误处理机制或批处理,那么它有望在通用异常上起作用。这个论点在我们的讨论中没有说服力,所以我很好奇其他观点。

4 个答案:

答案 0 :(得分:4)

是的,这是不好的做法。

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

实际上,我会考虑自动生成这些方法,但如果您不满意或无法使用能够为您生成这些方法的IDE,我建议您引用所有这些方法。对象上的字段,以及对象的类名,如intellij toString method

答案 1 :(得分:3)

在任何地方都不捕获通用Exception的主要原因是它还将包含RuntimeException,在正常情况下不应捕获该异常,因为它们在程序中始终代表 bug 。最好让它们传播和出现,以便开发人员可以注意到它并最终对其进行修复。

我不知道在toString方法的情况下是否应该进行任何其他的良好实践检查,但是我确定至少应该应用一般规则。

因此,最佳实践始终是捕获仅个检查过的异常,然后恢复,重新抛出它们或将它们重新包装为另一个异常(这是您的情况)。

答案 2 :(得分:3)

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

toString()的合同为:

  

...通常,toString方法返回一个字符串,该字符串“以文本形式表示”此对象。结果应该是简洁但内容丰富的表示形式,便于人们阅读...

在有效Java第三版(第12项)中,Bloch进一步坚持:

  

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

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

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

关于为什么从toString抛出异常是个坏主意,this post提供了一个很好的答案。

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

答案 3 :(得分:0)

应该通过失败的toString()方法来中断“正常流”吗?如果答案是否定的,则应使toString()方法“工作”。捕获异常并在结果中反映出来是一种可能性,或者是简单的日志输出。