在exception被捕获错设计后返回null

我总是遇到同样的问题,当在具有非void返回值的函数中捕获exception时,我不知道要返回什么。 以下代码段说明了我的问题。

public Object getObject(){ try{ ... return object; } catch(Exception e){ //I have to return something here but what?? return null; // is this a bad design?? } } 

所以我的问题是:

  • 返回null设计不好吗?
  • 如果是这样,什么被视为更清洁的解决方案?

谢谢。

我会说,如果你真的无法处理它,不要抓住exception。 并且不会将日志记录视为处理错误。 最好把它冒充给可以抛弃exception的人。

如果你必须返回一个值,并且null是唯一明智的东西,那就没有错。 只需记录下来并向用户说明应该做什么。 有一个unit testing,显示抛出的exception,所以开发人员可以看到你所接受的成语需要什么。 它还将测试以确保您的代码在应该的时候抛出exception。

我总是遇到同样的问题,当在具有非void返回值的函数中捕获exception时,我不知道要返回什么。

如果您不知道要返回什么,那么这意味着您不知道如何处理exception。 在那种情况下, 重新抛出它 。 请不要悄悄地吞下它 。 并且请不要返回null ,你不想强制代码的调用者写:

 Foo foo = bar.getFoo(); if (foo != null) { // do something with foo } 

这是恕我直言,一个糟糕的设计,我个人不喜欢写空检查(很多时候,使用null,而不是应该抛出exception)。

所以,正如我所说的,为方法添加一个throws子句,或者完全远程的try / catch块,或者如果有意义的话,保持try / catch(例如,如果你需要处理几个exception)并重新抛出exception或将其包装在自定义exception中。

相关问题

  • 如何避免Java中的“!= null”语句?

最重要的是,我不想返回null。 这是用户必须明确记住作为特殊情况处理的事情(除非他们期望为空 – 这是记录的)。 如果他们很幸运,他们会立即尊重它并遭受错误。 如果他们运气不好,他们会把它粘在一个集合中,以后会遇到同样的问题。

我想你有两个选择:

  1. 抛出exception。 这样客户端必须以某种方式处理它(因此我要么记录它和/或检查它)。 缺点是exception很慢并且不应该用于控制流程,因此我将此用于特殊情况(双关语)
  2. 您可以使用NullObject模式。

我遵循一种编码风格,我很少返回null。 如果/当我这样做时,这是明确记录的,因此客户可以满足它。

例外表示特殊情况。 假设你的代码应该返回一个对象,那么在路上肯定会出现问题 (网络错误,内存不足,谁知道?)因此你不应该只是通过返回null来阻止它。

但是,在许多情况下,您可以在文档中看到方法在发生此类情况时返回null。 然后该类的客户端可以依赖此行为并处理返回的null,没有什么不好的。 在第二个用法示例中,请参见它不是一个例外情况 – 该类被设计为在某些条件下返回null – 因此这样做完全没问题(但是要记录这个预期的行为)。

因此,在一天结束时,它实际上取决于你是否因为某种特殊方式而无法返回物体,或者你根本没有物体返回,这绝对没问题。

控制器最终应始终捕获exception。
传递给控制器是没有意义的
最好将原始exception抛出/返回堆栈。

我喜欢建议抛出exception的响应,但这意味着您已经将exception处理设计到了软件的体系结构中。

error handling通常包含3个部分:检测,报告和恢复。 根据我的经验,错误属于严重性类别(以下是缩写列表):

  • 仅记录调试
  • 暂停正在进行的操作并向用户报告,等待响应继续。
  • 用辩护的对话框放弃并终止程序。

您的错误应该被分类,处理应尽可能一致和一致。 如果每次编写新代码时都必须考虑如何处理每个错误,那么您的软件没有有效的error handling策略。 我希望有一个报告function,如果继续取决于用户的选择,则启动用户交互。

关于是否返回null(一个陈旧的模式,如果我曾经看过一个)的答案取决于什么函数记录错误,如果函数失败并且返回null,调用者可以/必须做什么,以及是否不是错误的严重性决定了额外的处理。

这是你的代码,这是一个不错的解决方案。 但是如果你共享你的代码,你就不会使用它,因为它会抛出意外的exception(如nullpointer)。

你当然可以使用

 public Object getObject() throws Exception {} 

这可以给父母function提供可用的信息,并会警告可能发生的事情。

关于如何处理例外的一些想法

  • 返回null是好还是坏设计取决于exception以及此代码段放置在系统中的位置。

  • 如果exception是NullPointerException,您可能会将catch块应用于某种程度上(如流控制)。

  • 如果它类似于InOException并且您无法对此进行任何操作,则应将Exception抛出到控制器。

  • 如果控制器是组件的外观,则将exception转换为可能在接口处发生的特定于组件的特定组件的可能exception。 并且详细信息包括原始exception作为嵌套exception。

基本上我会在Duffymo上同上,稍作补充:

正如他所说,如果你的调用者无法处理exception并恢复,那么就不要捕获exception。 让更高级别的function抓住它。

如果调用者需要做某事但应该适当地死掉,只需重新抛出exception即可。 喜欢:

 SomeObject doStuff() throws PanicAbortException { try { int x=functionThatMightThrowException(); ... whatever ... return y; } catch (PanicAbortException panic) { cleanUpMess(); throw panic; // <-- rethrow the exception } } 

您也可以重新打包例外,例如......

 catch (PanicAbortException panic) { throw new MoreGenericException("In function xyz: "+panic.getMessage()); } 

这就是为什么这么多java代码在if (x!=null) {...}子句中膨胀的原因。 不要创建自己的Null Pointer Exceptions。

正如Josha Blooch在“ Effective Java ”一书中所说, null是Java的关键字。

这个词识别一个没有指向任何其他内存位置的内存位置:IMO最好用关于function域的行为分离进行编码(例如:你等待A类对象,但是你收到了类型B的对象)和行为低级域名(例如:内存不可靠)。

我会编写你的例子:

 public Object getObject(){ Object objectReturned=new Object(); try{ /**business logic*/ } catch(Exception e){ //logging and eventual logic leaving the current ojbect (this) in a consistent state } return objectReturned; } 

无论是在getObject()的每次调用中创建一个完整的Object(然后是在不读取或写入objectReturned的情况下)。

但我更喜欢使用与NullPointerException相同的对象,因为有时这个exception很难修复。

我会说这是一个不好的做法。 如果收到null ,我如何知道object是否存在或发生了一些错误?

我的建议是

如果writtern类型是数组或Collection.Instead返回空集合或空数组,则永远不会返回NULL

当返回类型是Object时,返回null取决于方案。 但永远不要吞下Exception并返回NULL。

此外,如果您在任何方案中返回NULL,请确保在menthod中记录了这一点。