Java 检索方法是否应返回';空';或者在可以';不产生返回值?
我使用的是java语言,我有一个方法,如果找到一个对象,它应该返回一个对象 如果找不到,我是否应该:Java 检索方法是否应返回';空';或者在可以';不产生返回值?,java,exception,error-handling,null,Java,Exception,Error Handling,Null,我使用的是java语言,我有一个方法,如果找到一个对象,它应该返回一个对象 如果找不到,我是否应该: 返回空值 抛出异常 其他 哪种做法或习惯用法最好?我更喜欢只返回null,并依靠调用者适当地处理它。(因为没有更好的词)例外是,如果我绝对“肯定”此方法将返回一个对象。在这种情况下,失败是一个异常,应该并且应该抛出。与您正在使用的API保持一致。使用空对象模式或抛出异常。如果客户端代码了解找到和未找到之间的差异很重要,并且这应该是一个常规行为,那么最好返回null。然后,客户端代码可以决定执行什
哪种做法或习惯用法最好?我更喜欢只返回null,并依靠调用者适当地处理它。(因为没有更好的词)例外是,如果我绝对“肯定”此方法将返回一个对象。在这种情况下,失败是一个异常,应该并且应该抛出。与您正在使用的API保持一致。使用空对象模式或抛出异常。如果客户端代码了解找到和未找到之间的差异很重要,并且这应该是一个常规行为,那么最好返回null。然后,客户端代码可以决定执行什么操作。通常它应该返回null。调用该方法的代码应该决定是抛出异常还是尝试其他操作。这实际上取决于您是否希望找到该对象。如果你遵循例外应该用来表示某事的思想流派,那么,呃,例外已经发生了:
- 发现的物体;返回对象
- 未找到对象;抛出异常
否则,返回null。只有在异常确实是错误时才会抛出异常。如果预期对象不存在,则返回null
否则,这是一个偏好问题。如果您总是希望找到一个值,那么如果该值丢失,则抛出异常。例外情况意味着存在问题 如果该值可能丢失或存在,并且两者对应用程序逻辑都有效,则返回null
更重要的是:您在代码的其他地方做什么?一致性很重要。作为一般规则,如果该方法应始终返回对象,则使用异常。如果您预期偶尔会出现空值,并希望以某种方式处理它,请使用空值
无论您做什么,我强烈建议您不要使用第三种方法:返回一个表示“WTF”的字符串。取决于未找到对象的含义 如果是正常状态,则返回null。这只是偶尔会发生的事情,打电话的人应该检查一下 如果是错误,则抛出异常,调用方应决定如何处理缺少对象的错误条件
最终会起作用,尽管大多数人通常认为只有在异常发生时才使用异常。这是一个很好的做法。
< P>只要它返回对对象的引用,返回null就应该是好的。但是,如果它返回了整个血腥的东西(比如C++):“返回BLAH”,而不是“返回和BLAH”(或“BLAH”是指针)。,则不能返回NULL,因为它不是“object”类型。在这种情况下,我将如何处理该问题,即引发异常或返回未设置成功标志的空白对象。返回NULL而不是引发异常,并在API文档中清楚地记录NULL返回值的可能性。如果没有调用代码不遵守API并检查null情况,这很可能会导致某种“null指针异常”: 在C++中,我可以想出3种不同的方法来创建一个对象。 选项A
Object *findObject(Key &key);
当找不到对象时返回null。又好又简单。我会选择这个。下面的替代方法适用于那些不讨厌情妇的人
选项B
void findObject(Key &key, Object &found);
传入对将接收对象的变量的引用。当找不到对象时,该方法引发异常。如果不希望真的找不到对象,那么这种约定可能更合适——因此您会抛出一个异常来表示这是一个意外情况
选项C
bool findObject(Key &key, Object &found);
当找不到对象时,该方法返回false。与选项A相比,此选项的优点是,您可以在一个明确的步骤中检查错误情况:
if (!findObject(myKey, myObj)) { ...
不要认为有人提到异常处理中的开销-需要额外的资源来加载和处理异常,除非它是一个真正的应用程序终止或进程停止事件(继续下去将弊大于利)我会选择传回调用环境认为合适的值。我同意这里的共识(如果“未找到”是正常的可能结果,则返回null;如果情况的语义要求始终找到对象,则抛出异常)
然而,根据你的具体情况,还有第三种可能是有意义的。您的方法可以在“not found”(未找到)条件下返回某种类型的默认对象,从而允许调用代码确保它将始终接收有效对象,而无需进行null检查或异常捕获。如果null从不表示错误,则只需返回null即可 如果null始终是错误,则抛出异常 如果null有时是一个异常,则编写两个例程。一个例程引发异常,另一个是布尔测试例程,它在输出参数中返回对象,如果找不到对象,该例程将返回false 很难误用试一试的惯例。很容易忘记检查null 所以当null是一个错误时,您只需编写
object o = FindObject();
当null不是错误时,可以编写如下代码
if (TryFindObject(out object o)
// Do something with o
else
// o was not found
或者返回一个选项
选项基本上是一个容器类,它强制客户机处理案例。Scala有这个概念,请查看它的API
然后在这个对象上有像T getOrElse(T valueIfNull)这样的方法
..., bool verify = true)
is_present(key)
find(key) throws Exception
Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);
bool TryFindObject(RequestParam request, out ResponseParam response)
...
if(TryFindObject(request, out response)
{
handleSuccess(response)
}
else
{
handleFailure()
}
...
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
* @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
* @author Seval
*
*/
public class Example2 {
/**
* Constructor of Example2
* @throws Exception
*/
public Example2() throws Exception{
throw new Exception("Please set the \"obj\"");
}
}