我有一个域模型类,该类具有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()
的一般情况,而我大多数都同意,如果您正在执行通用错误处理机制或批处理,那么它有望在通用异常上起作用。这个论点在我们的讨论中没有说服力,所以我很好奇其他观点。
答案 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()方法“工作”。捕获异常并在结果中反映出来是一种可能性,或者是简单的日志输出。