java 异常被捕获错误设计后返回 null

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2168397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:49:08  来源:igfitidea点击:

Is returning null after exception is caught bad design

javaexceptionreturn-value

提问by woolagaroo

I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return. The following code snippet illustrates my problem.

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

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

So my questions are:

所以我的问题是:

  • Is return null bad design?
  • If so what is seen as a cleaner solution??
  • return null 是糟糕的设计吗?
  • 如果是这样,什么被视为更清洁的解决方案?

thanks.

谢谢。

回答by duffymo

I would say don't catch the exception if you really can't handle it. And logging isn't considered handling an error. Better to bubble it up to someone who can by throwing the exception.

我会说如果您真的无法处理它,请不要捕获异常。并且不考虑日志记录处理错误。最好通过抛出异常将其冒泡给可以的人。

If you must return a value, and null is the only sensible thing, there's nothing wrong with that. Just document it and make it clear to users what ought to be done. Have a unit test that shows the exception being thrown so developers coming after you can see what the accepted idiom needs to be. It'll also test to make sure that your code throws the exception when it should.

如果您必须返回一个值,而 null 是唯一明智的做法,那没有任何问题。只需记录它并向用户说明应该做什么。有一个单元测试,显示抛出的异常,以便开发人员可以看到接受的习惯用法是什么。它还将测试以确保您的代码在应该抛出异常时抛出异常。

回答by Pascal Thivent

I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return.

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

If you don't know what to return, then it means that you don't know how to handle the exception. In that case, re-throw it. Please, don't swallow it silently. And please, don't return null, you don't want to force the caller of the code to write:

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

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

This is IMHO a bad design, I personally hate having to write null-checks (many times, null is used where an exception should be thrown instead).

恕我直言,这是一个糟糕的设计,我个人讨厌必须编写空检查(很多时候,在应该抛出异常的地方使用空值)。

So, as I said, add a throwsclause to the method and either totally remote the try/catch block or keep the try/catch if it makes sense (for example if you need to deal with several exceptions) and rethrow the exception as is or wrap it in a custom exception.

因此,正如我所说,throws在方法中添加一个子句,要么完全远离 try/catch 块,要么保留 try/catch(如果它有意义)(例如,如果您需要处理多个异常)并按原样重新抛出异常或将其包装在自定义异常中。

Related questions

相关问题

回答by Brian Agnew

Above all I prefer not to return null. That's something that the user has to explicitly remember to handle as a special case (unless they're expecting a null - is this documented). If they're lucky they'll deference it immediately and suffer an error. If they're unlucky they'll stick it in a collection and suffer the same problem later on.

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

I think you have two options:

我认为你有两个选择:

  1. throw an exception. This way the client has to handle it in some fashion (and for this reason I either document it and/or make it checked). Downsides are that exceptions are slow and shouldn't be used for control flow, so I use this for exceptional circumstances (pun intended)
  2. You could make use of the NullObjectpattern.
  1. 抛出异常。这样,客户端必须以某种方式处理它(因此我要么记录它和/或检查它)。缺点是异常很慢,不应该用于控制流,所以我在特殊情况下使用它(双关语)
  2. 您可以使用NullObject模式。

I follow a coding style in which I rarely return a null. If/when I do, that's explicitly documented so clients can cater for it.

我遵循一种很少返回空值的编码风格。如果/当我这样做时,会明确记录下来,以便客户可以满足。

回答by Peter Perhá?

Exceptions denote exceptionalcases. Assuming your code was supposed to return an object, something must have gone wrongon the way (network error, out of memory, who knows?) and therefore you should not just hush it by returning null.

例外表示例外情况。假设您的代码应该返回一个对象,那么途中一定出了问题(网络错误、内存不足,谁知道呢?),因此您不应该只是通过返回 null 来掩盖它。

However, in many cases, you can see in documentation that a method returns a null when such and such condition occurs. The client of that class can then count on this behaviour and handle a null returned, nothing bad about that. See, in this second usage example, it is not an exceptional case - the class is designed to return null under certain conditions - and therefore it's perfectly fine to do so (but do document this intended behaviour).

但是,在许多情况下,您可以在文档中看到,当发生这样那样的情况时,方法会返回 null。然后该类的客户端可以依靠这种行为并处理返回的空值,这没什么不好的。请看,在第二个使用示例中,这不是一个例外情况——该类旨在在某些条件下返回 null——因此这样做完全没问题(但要记录这种预期的行为)。

Thus, at the end of the day, it really depends on whether you can't return the object because of something exceptional in your way, or you simply have no object to return, and it's absolutely fine.

因此,归根结底,这实际上取决于您是因为自己的方式异常而无法归还对象,还是根本没有归还对象,这绝对没问题。

回答by Kb.

Exceptions should always be caught by the controller in the end.
Passing a <null> up to the controller makes no sense.
Better to throw/return the original exception up the stack.

异常应该总是最终被控制器捕获。
将 <null> 传递给控制器是没有意义的
最好在堆栈中抛出/返回原始异常。

回答by Bruce

I like the responses that suggest to throw an exception, but that implies that you have designed exception handling into the architecture of your software.

我喜欢建议抛出异常的响应,但这意味着您已将异常处理设计到您的软件架构中。

Error handling typically has 3 parts: detection, reporting, and recovery. In my experience, errors fall into classes of severity (the following is an abbreviated list):

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

  • Log for debug only
  • Pause whatever is going on and report to user, waiting for response to continue.
  • Give up and terminate the program with an apologetic dialogue box.
  • 仅用于调试的日志
  • 暂停正在发生的任何事情并向用户报告,等待响应继续。
  • 放弃并用一个道歉对话框终止程序。

Your errors should be classified and handling should be as generically and consistently as possible. If you have to consider how to handle each error each time you write some new code, you do not have an effective error handling strategy for your software. I like to have a reporting function which initiates user interaction should continuation be dependent on a user's choice.

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

The answer as to whether to return a null (a well-worn pattern if I ever saw one) then is dependent on what function logs the error, what can/must the caller do if the function fails and returns the null, and whether or not the severity of the error dictates additional handling.

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

回答by oneat

It's your code and it's not bad solution. But if you share your code you Shoudn't use it because it can throw unexpected exception (as nullpointer one).

这是你的代码,它不是一个糟糕的解决方案。但是,如果您共享代码,则不应使用它,因为它可能会引发意外异常(作为空指针之一)。

You can of course use

你当然可以使用

public Object getObject() throws Exception {}

which can give to parent function usable information and will warn that something bad can happen.

它可以为父函数提供可用信息,并警告可能会发生一些不好的事情。

回答by stacker

Some thoughts on how to handle Exceptions

关于如何处理异常的一些想法

  • Whether returning null would be good or bad design depends on the Exception and where this snippet is placed in your system.

  • If the Exception is a NullPointerException you probably apply the catch block somewhat obtrusive (as flow control).

  • If it is something like IOException and you can't do anything against the reason, you should throw the Exception to the controller.

  • If the controller is a facade of a component he, translate the Exception to well documented component-specific set of possible Exceptions, that may occur at the interface. And for detailed information you should include the original Exception as nested Exception.

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

  • 如果 Exception 是 NullPointerException,您可能会应用有点突兀的 catch 块(作为流量控制)。

  • 如果它是类似 IOException 的东西并且你不能做任何事情,你应该将 Exception 抛出到控制器。

  • 如果控制器是组件的外观,则将异常转换为记录良好的特定于组件的可能异常集,这可能发生在接口上。对于详细信息,您应该将原始异常包含为嵌套异常。

回答by Jay

Basically I would ditto on Duffymo, with a slight addition:

基本上我会在 Duffymo 上同上,并稍微补充一下:

As he says, if your caller can't handle the exception and recover, then don't catch the exception. Let a higher level function catch it.

正如他所说,如果您的调用者无法处理异常并恢复,则不要捕获异常。让更高级别的函数捕获它。

If the caller needs to do something but should then appropriately die itself, just rethrow the exception. Like:

如果调用者需要做某事但应该适当地自行死亡,只需重新抛出异常。喜欢:

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

You might also repackage the exception, like ...

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

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

回答by sal

This is why so much java code is bloated with if (x!=null) {...}clauses. Don't create your own Null Pointer Exceptions.

这就是为什么这么多 java 代码被if (x!=null) {...}子句膨胀的原因。不要创建自己的空指针异常。