在 toString 实现中捕获通用异常 - 不好的做法?
Catching generic Exception in a toString implementation - bad practice?
我有一个域模型 class,它有一个 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
。
我的印象是,这是一种不好的做法,而且 "code smell"。 toString()
甚至需要这个检查的事实对我来说是糟糕设计的症状。但是一位同事问我,在 toString()
中捕获通用 Exception
到底有什么问题,因为捕获的 Exception
会进一步传播。
我认为它至少违反了 KISS 原则,因为像这里的 toString()
这样的简单方法被指示为需要特殊的异常处理。
所以在 toString() 中有一个包罗万象的块是不是代码味道?
我找到的答案要么是针对捕获通用 Exception
的一般情况,我同意其中的大多数,如果您正在执行通用错误处理机制或批处理,那么它有望在一般异常。这个论点在我们的讨论中没有说服力,所以我很好奇其他意见。
不在任何地方捕获通用异常的主要原因是它也会包含 RuntimeExceptions,在正常情况下不应该捕获,因为它们总是代表一个 bug该程序。最好让它们传播和出现,以便开发人员能够注意到它并最终修复它。
我不知道在 toString
方法的情况下是否应该应用任何额外的良好实践检查,但我确信至少应该应用一般规则。
因此,最佳做法始终是捕获仅检查的异常,然后恢复、重新抛出它们或将它们重新包装到另一个异常中(这是您的情况) .
是的,这是不好的做法。
toString 方法的目的是为您的 class 提供程序员可读的表示形式。您不应在此方法中包含任何方法调用,包括 getter。
事实上,我会考虑 not 自动生成这些方法很臭,但假设您不习惯或无法使用 IDE 为您生成这些方法,我建议包括对对象上所有字段的引用,以及对象的 class 名称,就像 intellij toString method
所做的那样
对于toString()
方法,catchingException
不一定是不好的做法。然而,re-throwing它是有问题的部分。
toString() 的合同是:
... In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read...
在 Effective Java 第三版(第 12 项)中,Bloch 进一步坚持:
When practical, the toString method should return all of the interesting information contained in the object.
因此,如果这需要调用可能抛出已检查异常的方法,那就这样吧,捕获这些异常很有意义。
但是: 引发的已检查异常提供有关对象状态的信息。与 toString
的目标一致,在 toString
.
返回的消息中包含异常条件可能是个好主意
至于为什么从 toString
中抛出异常是个坏主意, 提供了很好的答案。
建议: 使用特定的异常类型捕获检查的异常,并将此事实集成到 toString()
消息中,而不是传播它。
"normal flow" 是否应该被失败的 toString() 方法中断?如果答案是否定的,您应该使 toString() 方法 "work"。捕获异常并将其反映在结果中是一种可能性,或者是简单的日志输出。
我有一个域模型 class,它有一个 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
。
我的印象是,这是一种不好的做法,而且 "code smell"。 toString()
甚至需要这个检查的事实对我来说是糟糕设计的症状。但是一位同事问我,在 toString()
中捕获通用 Exception
到底有什么问题,因为捕获的 Exception
会进一步传播。
我认为它至少违反了 KISS 原则,因为像这里的 toString()
这样的简单方法被指示为需要特殊的异常处理。
所以在 toString() 中有一个包罗万象的块是不是代码味道?
我找到的答案要么是针对捕获通用 Exception
的一般情况,我同意其中的大多数,如果您正在执行通用错误处理机制或批处理,那么它有望在一般异常。这个论点在我们的讨论中没有说服力,所以我很好奇其他意见。
不在任何地方捕获通用异常的主要原因是它也会包含 RuntimeExceptions,在正常情况下不应该捕获,因为它们总是代表一个 bug该程序。最好让它们传播和出现,以便开发人员能够注意到它并最终修复它。
我不知道在 toString
方法的情况下是否应该应用任何额外的良好实践检查,但我确信至少应该应用一般规则。
因此,最佳做法始终是捕获仅检查的异常,然后恢复、重新抛出它们或将它们重新包装到另一个异常中(这是您的情况) .
是的,这是不好的做法。
toString 方法的目的是为您的 class 提供程序员可读的表示形式。您不应在此方法中包含任何方法调用,包括 getter。
事实上,我会考虑 not 自动生成这些方法很臭,但假设您不习惯或无法使用 IDE 为您生成这些方法,我建议包括对对象上所有字段的引用,以及对象的 class 名称,就像 intellij toString method
所做的那样对于toString()
方法,catchingException
不一定是不好的做法。然而,re-throwing它是有问题的部分。
toString() 的合同是:
... In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read...
在 Effective Java 第三版(第 12 项)中,Bloch 进一步坚持:
When practical, the toString method should return all of the interesting information contained in the object.
因此,如果这需要调用可能抛出已检查异常的方法,那就这样吧,捕获这些异常很有意义。
但是: 引发的已检查异常提供有关对象状态的信息。与 toString
的目标一致,在 toString
.
至于为什么从 toString
中抛出异常是个坏主意,
建议: 使用特定的异常类型捕获检查的异常,并将此事实集成到 toString()
消息中,而不是传播它。
"normal flow" 是否应该被失败的 toString() 方法中断?如果答案是否定的,您应该使 toString() 方法 "work"。捕获异常并将其反映在结果中是一种可能性,或者是简单的日志输出。