Java 正常程序逻辑和异常

Java 正常程序逻辑和异常,java,exception,Java,Exception,我正在查看一些团队代码,发现如下内容: MyObj obj = null; try { obj = myService.findObj(objId) } catch (MyObjNotFoundException e) { // The object wasn't found, it's the "normal" path // Here they create the object in DB (but don't touch the obj variable) // The

我正在查看一些团队代码,发现如下内容:

MyObj obj = null;

try {
  obj = myService.findObj(objId)
} catch (MyObjNotFoundException e) {
  // The object wasn't found, it's the "normal" path
  // Here they create the object in DB (but don't touch the obj variable)
  // There is about 60 line of code
}
if (obj != null) {
  // The object already exist, logs are written and some queue is filled
  // with current objId to be processed later on
}
在我的评论中,我将指出,从性能或可维护性的角度来看,使用
异常
来控制正常的程序流不是一个好主意。
最好是修改服务以返回
null
,而不是抛出异常,但是:

  • 我不确定他们是否拥有该服务(可能是另一个项目/团队)
  • 他们可能真的需要这个例外
因此,除了性能问题,除非不抛出异常,否则将无法解决,我想给他们一段“更干净”的代码

我的想法是知道服务只发送此异常:

try {
  obj = myService.findObj(objId)
} finally {
}

if (obj == null) {
  // The object wasn't found, it's the "normal" path
} else {
  // The object already exist, logs are written and some queue is filled
  // with current objId to be processed later on
}
你会走这边吗? 它真的在可读性上迈出了一步吗? 你能想点别的吗


非常感谢。

我喜欢使用exception而不是返回null,因为您可以将发生错误的原因传递给用户。在我看来,这比只返回null要好。

我喜欢使用exception而不是返回null,因为您可以将发生错误的原因传递给用户。在我看来,这比只返回null要好。

这样做没有对错之分。我只能告诉您,-模式早在J2EE和EJB2.0的早期就已经存在了。在一段典型的业务逻辑涉及捕获大约1700万个恼人的已检查异常的时候抛出的子类很常见,只是为了将它们中的大多数打包到
RuntimeExceptions
中,以便能够将它们重新带回天堂


如今,返回
null
可能再次变得更加流行,因为找不到对象也不是例外,而
null
正是这种语义。除此之外,
null
并不比
ObjectNotFoundException
好多少。只是口味的问题。

没有正确或错误的方法。我只能告诉您,-模式早在J2EE和EJB2.0的早期就已经存在了。在一段典型的业务逻辑涉及捕获大约1700万个恼人的已检查异常的时候抛出的子类很常见,只是为了将它们中的大多数打包到
RuntimeExceptions
中,以便能够将它们重新带回天堂


如今,返回
null
可能再次变得更加流行,因为找不到对象也不是例外,而
null
正是这种语义。除此之外,
null
并不比
ObjectNotFoundException
好多少。只是品味的问题。

就我个人而言,我认为你的改变根本没有什么大的不同。也许对Java字节优化有更深入了解的人可以插话,但我希望异常处理的额外“重量”仍然内置,即使异常块中没有任何内容

避免将异常处理用作流控制的最大原因之一是抛出异常的代价。编译器不是为优化异常处理而设计的;他们希望只有在特殊情况下才会抛出它们(请原谅双关语)——即:当应用程序遇到意外情况时。因此,所有重点都放在优化标准流量控制逻辑(if/else、for、while等)。从可读性和性能的角度来看,将异常用于流控制是一个糟糕的想法

找不到对象不是意外情况。事实上,它是逻辑/流程图的一部分,应该在开发代码之前进行设计,并根据预期结果记录正确的返回值。DB响应失败将是一种可接受的异常情况—这种情况很少发生,实际上是一种意外状态


基本上,在我看来,你提出的改变使阅读变得更加复杂。问题的核心是抛出异常。如果这无法补救,我不相信你空洞的尝试/捕获真的有很大帮助。如果有什么区别的话,您的代码首先会说您计划忽略所有未找到的异常,但稍后,您会选择处理它,这有点矛盾。如果从中获得性能提升,我会理解这一点,但正如我所说的,我认为最昂贵的部分是抛出异常,而不是实际捕获异常。

就我个人而言,我认为您的更改不会带来任何显著的变化。也许对Java字节优化有更深入了解的人可以插话,但我希望异常处理的额外“重量”仍然内置,即使异常块中没有任何内容

避免将异常处理用作流控制的最大原因之一是抛出异常的代价。编译器不是为优化异常处理而设计的;他们希望只有在特殊情况下才会抛出它们(请原谅双关语)——即:当应用程序遇到意外情况时。因此,所有重点都放在优化标准流量控制逻辑(if/else、for、while等)。从可读性和性能的角度来看,将异常用于流控制是一个糟糕的想法

找不到对象不是意外情况。事实上,它是逻辑/流程图的一部分,应该在开发代码之前进行设计,并根据预期结果记录正确的返回值。DB响应失败将是一种可接受的异常情况—这种情况很少发生,实际上是一种意外状态

基本上,在我看来,你提出的改变使阅读变得更加复杂。问题的核心是抛出异常。如果这无法补救,我不相信你的空洞的尝试/捕获
try {
    obj = myService.findObj(objId)
} 
catch (ObjectNotFoundException) {
    // ignore, obj stays null
}

if (obj == null) {
    // The object wasn't found, it's the "normal" path
} 
else {
    // The object already exist, logs are written and some queue is filled
    // with current objId to be processed later on
}