应该检索方法返回'null'或投掷的一个例外时,它不能产生的回报的价值?[关闭]

StackOverflow https://stackoverflow.com/questions/175532

  •  05-07-2019
  •  | 
  •  

我有一个方法,应该是返回的一个目的,如果它被发现。

如果不找到,我应该:

  1. return null
  2. 扔一个例外
  3. 其他的
有帮助吗?

解决方案

如果你总是希望找到一个值,然后扔例外,如果是失踪。该例外的意思是,有一个问题。

如果值可能丢失或本,两者都是有效应用逻辑,然后返回一个空。

更重要的是:你是做什么的其他地方的代码?一致性是重要的。

其他提示

只能扔一个例外,如果它确实是一个错误。如果这是预期行为的对象不存在,返回的空。

否则,它是一个偏好的问题。

作为一般规则,如果方法应该总是返回的一个目,然后再与的例外。如果你预料的偶然的空想,以处理它在一个特定的方式,与空。

不管你做什么,我强烈建议对第三个选择:回串说"你".

如果null从来没有表示一个错误的话,就返回空。

如果空始终是一个错误然后再扔一个例外。

如果null有时是一个异常然后码两个程序。一个例行抛出的一个例外,另一个为布尔测试程序,返回的对象在一个输出参数和程序返回的一个假如果对象是没有找到。

这很难被滥用的一个尝试的程序。这是真的很容易忘记检查的空。

那么时空是一个错误你只是写信

object o = FindObject();

时空不是一个错误,你可以代码喜欢的东西

if (TryFindObject(out object o)
  // Do something with o
else
  // o was not found

我只是想扼要提到的选项之前,把一些新的问题:

  1. return null
  2. 扔一个例外
  3. 使用空对象的图案
  4. 提供一个布尔参数,以你的方法,这样的呼叫者可以选择如果他想要你把一个异常
  5. 提供一个额外的参数,这样的呼叫者可以设置一个值的其他回来如果没有价值的发现

或者你可能将这些选项:

提供若干重载版本的你吸气,这样的呼叫者可以决定走哪条路。在大多数情况下,只有第一个具有执行搜索算法,以及其他的人就围绕第一个:

Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);

甚至如果你选择仅仅提供一个实现,可能要使用一个命名的公约》那样,澄清合同,它可以帮助你,你应该曾经决定增加其他的实现。

你不应该过度使用它,但是它可以有帮助,espeacially当编写一个助手类将使用数百种不同的应用程序与许多不同的错误处理公约。

使用空对象的图案或投掷的一个例外。

是一致的,与API(s)使用。

只是问问自己:"它是一个特殊的情况,目的是找不到"?如果预计发生的正常课程的程序,你也许不应该提出一个例外(由于它不是特殊的行为)。

短短的版本:使用的例外情况处理特殊的行为,而不是为处理正常流动的控制你的程序。

-艾伦。

它取决于如果你的语言和代码促进:LBYL(看起来之前你飞跃) 或 EAFP(更容易请求原谅比的权限)

LBYL说你应该检查的价值(因此返回null)
EAFP说只是尝试的动作,看看如果失败(扔一个例外)

虽然我同意以上..例外情况应该用于特殊/错误的条件和返回的一个空是最佳的时候使用调查。


EAFP与LBYL在蟒蛇:
http://mail.python.org/pipermail/python-list/2003-May/205182.html (档案网络)

优点投掷的一个例外:

  1. 吸尘器控制流动在您的电话码。 检查空注入一个条件分支,这本身是处理通过尝试/赶上。检查空并不表明它是什么你检查-你检查空因为你是在寻找一个错误你期待,或者是你检查空所以你不把它传上进一步downchain?
  2. 消除模糊不清什么是"null"的意思。 是null代表的错误或是空的,什么是实际存在的价值?很难说当你只有一件事为基础,确定。
  3. 改进之间的一致性方法的行为,在应用程序。 例外情况通常是暴露在签名方法,这样你更能理解什么样的边界情况的方法的应用程序中的帐户为,以及什么样的信息应用程序可以作出反应,在可预见的方式。

为更多的解释的实例,参见: http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/

例外的是与设计相关的合同。

该接口的对象实际上是合同之间的两个对象,呼叫者必须满足合同的或其他的接收器可能只是失败的一个例外。有两种可能的合同

1)所有输入的方法是有效的,在这种情况下,必须返回null当的对象是没有找到。

2)只有一些投入是有效的,即那些结果在找到对象。在这种情况下必须提供的第二种方法,允许调用者,以确定如果其输入是正确的。例如

is_present(key)
find(key) throws Exception

如果且只有如果你提供这两种方法的第2次合同,你被允许扔一个例外是什么也没有发现!

我更喜欢只是返回的一个空,并依靠呼叫者适当地处理它。在(由于缺乏一个更好的词)例外是,如果我绝对'的某些'这一方法将会返回一个对象。在这种情况下失败是一种特殊的应和应该扔掉。

取决于什么意味着,对象是没有找到。

如果它是一个正常的国家的事务,然后返回null。这是仅有的东西,可能会发生一次在一段时间,打电话者应该检查它。

如果它是个错误,然后再扔一个例外,打电话者应该决定做什么用的错误的条件失踪的对象。

最终,无论是会的工作,虽然大多数人们一般认为这很好的做法仅仅使用的例外情况时的东西,好了,特殊的事情发生了。

这里有一些更多的建议。

如果回返集合,避免返回空,返回的一个空集,这使得枚举更容易处理,而不null检查一下。

几个。净API的使用模式的一个thrownOnError参数,这给人的呼叫者的选择,因为它是否真的是一个特殊情况或不,如果对象是没有找到。类型。GetType是这样的一个例子。另一种常见的模式与BCL是TryGet的模式,其中一个布尔的返回和价值是通过输出参数。

你也可以考虑的空对象的图案在一些情况下,既可以默认或一版本没有的行为。关键的是避免空检查整个码的基础。在这里看到更多的信息 http://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx

在一些职能添加的一个参数:

..., bool verify = true)

真正的装置扔了,假装置返回的一些错误返回的价值。这种方式,谁使用这种功能有两个选项。默认应该是真的,受益的那些人忘记了错误的处理。

返回的一个空而不是扔一个例外和明确的文件的可能性的一个空返回价值在API文件。如果叫的代码不幸的API,并检查为零的情况下,它最有可能导致某种形式的"null指的例外"不管怎么说:)

C++的,我能想到的3个不同的口味的设立一个方法,找到一个对象。

选项一

Object *findObject(Key &key);

Return null对象时可以不被发现。好的,简单的。我会去的这一个。备选办法下的人不恨出参数。

选项B

void findObject(Key &key, Object &found);

通过在一个参照的变量,将收到的对象。该方法引发的一个例外的对象时可以不被发现。这项公约可能是更合适的,如果它不是真正的预期对象没有被发现--因此你扔的一个例外表示,这是一个意想不到的情况。

选项C

bool findObject(Key &key, Object &found);

该方法返回虚假的对象时可以不被发现。这样做的优点在选择一个是,你可以检查出错误的情况下在一个明确步骤:

if (!findObject(myKey, myObj)) { ...

仅提到的情况下,空不被认为是一个特殊的行为我绝对尝试的方法,它是清楚的,不需要"读书"或"看起来之前你飞跃"正如在这里所说的

所以基本上:

bool TryFindObject(RequestParam request, out ResponseParam response)

这意味着用户的代码也将清楚

...
if(TryFindObject(request, out response)
{
  handleSuccess(response)
}
else
{
  handleFailure()
}
...

如果这是非常重要的客户代码知道之间的差异发现,并没有发现与这应该是一个日常的行为,那么它最好要返回null。客户代码然后可以决定做什么。

一般应该返回空。代码呼吁的方法应该决定是否要扔一个例外或尝试的东西。

或返回的选择

一种选择基本上是一个容器类部队的客户来处理的摊情况。斯卡拉拥有这一概念,看看它是API。

然后你有的方法,如T getOrElse(T valueIfNull)上这个目的thet返回找到对象,或allternative客户specifieces.

不幸的是JAVA是不一致的,如果你想入非现有的关键资源包,你没发现异常,当你要求的价值从地图上你获得空,如果它不存在。所以我会变化的赢家回答以下,如果发现价值可以为空,则提出异常的时找不到,否则返回的空。因此,按照该规则有一个例外,如果您需要知道为什么值没有找到然后一直提出异常,或者..

只要它应该返回 参考 到目,返回的一个空应该是不错的。

然而,如果是返回的整个血腥的事情(如C++如果你这样做:'回报,等等等等;"而不是"返回&等等;'(或'等等'是指针),然后你不能返回空,因为它没有类型的"object".在这种情况下,把一个异常,或是返回的一个空白的对象,没有一个成功的标志的设置是我会怎样做法的问题。

不认为任何人提到开销在例外处理--需要额外的资源来装载和处理异常,所以除非其真正的程序杀害或处理停止的事件(会前将造成更多的伤害),我会选择传递回有价值的调环境的可能解释,因为它认为合适的。

我同意什么似乎是协商一致在这里(return null if"未找到"是一个正常的可能的结果,或扔一个例外,如果该语义学的情况要求的对象总是被发现)。

然而,有一个第三种可能性可能会使意义上取决于您的特殊情况。你的方法可能会返回一个默认对象的某种形式的"未找到"的条件,允许叫码得到保证,它将始终得到一个有效的对象而不需要空检查或例外。

返回的一个空,例外是完全的:一些你的代码并不是预期的。

例外情况应该是 特殊.Return null 如果它是有效的返回的一个空.

愿意返回null--

如果呼叫者使用它,而不检查,异常发生有权利。

如果呼叫者不真正地使用它,不税他 try/catch

如果的方法返回收,然后返回的一个空集合(如赛义德段)。但是请不集中。EMPTY_LIST或这样的!(情况下的Java)

如果方法retrives一个单一的对象,那么你有一些选择。

  1. 如果该方法应该永远找不到结果和它是一个真正的例外情况下没有找到对象的,那么你应该扔一个例外(在Java:请一个未经检查的例外)
  2. (Java仅)如果您可以容忍的方法引发的一个检查例外扔的一个项目的具体ObjectNotFoundException等。在这种情况下编译器说你,如果你忘记了处理例外情况。(这是我的首选的处理没发现的东西。)
  3. 如果你说这是真确定,如果对象是未找到和您的方法的名字就像findBookForAuthorOrReturnNull(..),然后您可以返回空。在这种情况下它 强烈 recomminded使用某种静态检查或编译器检查,这可以防止提领的结果没有一个空检查。在Java的情况下可以例如。置的代(见DefaultAnnotation在 http://findbugs.sourceforge.net/manual/annotations.html)或用浏览器-检查。

小心点,如果你决定要返回的一个空。如果你不是唯一的程序在项目中,你将得到NullPointerExceptions(Java或任何其他语言)在运行时间!所以不要返回null不检查在编制时间。

如果您使用的图书馆或另一类引发一个例外,你应该 重新引发 它。这里就是一个例子。Example2.java 是像图书馆和Example.java 使用它的对象。Main.java 是一个例子来处理这种例外。你应该显示出有意义的消息(如果需要的话)堆跟踪用户在叫一边。

Main.java

public class Main {
public static void main(String[] args) {
    Example example = new Example();

    try {
        Example2 obj = example.doExample();

        if(obj == null){
            System.out.println("Hey object is null!");
        }
    } catch (Exception e) {
        System.out.println("Congratulations, you caught the exception!");
        System.out.println("Here is stack trace:");
        e.printStackTrace();
    }
}
}

Example.java

/**
 * Example.java
 * @author Seval
 * @date 10/22/2014
 */
public class Example {
    /**
     * Returns Example2 object
     * If there is no Example2 object, throws exception
     * 
     * @return obj Example2
     * @throws Exception
     */
    public Example2 doExample() throws Exception {
        try {
            // Get the object
            Example2 obj = new Example2();

            return obj;

        } catch (Exception e) {
            // Log the exception and rethrow
            // Log.logException(e);
            throw e;
        }

    }
}

Example2.java

 /**
 * Example2.java
 * @author Seval
 *
 */
public class Example2 {
    /**
     * Constructor of Example2
     * @throws Exception
     */
    public Example2() throws Exception{
        throw new Exception("Please set the \"obj\"");
    }

}

这实际上取决于如果你想找的对象,或者不。如果遵循该学院以为例外情况应该用于指示一些东西,好吧,呃,卓越的已发生,然后:

  • 目;返回的对象
  • 目未发现;扔异常

否则,返回的空。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top