我使用java语言,我有一个方法,如果它被找到,应该返回一个对象。
如果没有找到,我是否应该:
返回null 抛出异常 其他
哪一个是最好的实践或习语?
我使用java语言,我有一个方法,如果它被找到,应该返回一个对象。
如果没有找到,我是否应该:
返回null 抛出异常 其他
哪一个是最好的实践或习语?
当前回答
如果您正在使用抛出异常的库或其他类,则应该重新抛出异常。这里有一个例子。Example2.java类似于library,而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\"");
}
}
其他回答
例外情况与契约式设计有关。
一个对象的接口实际上是两个对象之间的契约,调用方必须满足契约,否则接收方可能会异常失败。有两种可能的契约
1)所有输入的方法都是有效的,在这种情况下,当对象没有找到时必须返回null。
2)只有某些输入是有效的,即导致找到对象的输入。在这种情况下,您必须提供第二个方法,允许调用者确定其输入是否正确。例如
is_present(key)
find(key) throws Exception
当且仅当你提供了第二个契约的两个方法,你被允许抛出异常,但什么都没有发现!
这取决于你是否希望找到这个物体。如果你遵循学校的思想,认为exceptions应该用来表示某事,那么,嗯,呃,exceptions已经发生了:
对象发现;返回对象 没有找到对象;抛出异常
否则,返回null。
我同意这里的共识(如果“未找到”是一个正常的可能结果,则返回null,或者如果情况的语义要求始终找到对象,则抛出异常)。
然而,根据你的具体情况,还有第三种可能是有意义的。您的方法可以在“not found”条件下返回某种类型的默认对象,允许调用代码确保它总是接收到有效的对象,而不需要进行空检查或异常捕获。
我只是想概括一下之前提到的选项,并添加一些新的选项:
返回null 抛出异常 使用空对象模式 为您的方法提供一个布尔参数,以便调用者可以选择是否希望您抛出异常 提供一个额外的参数,以便调用者可以设置一个值,如果没有找到值,则返回该值
或者你可以把这些选项结合起来:
提供getter的多个重载版本,以便调用者可以决定采用哪种方式。在大多数情况下,只有第一个有搜索算法的实现,其他的只是围绕着第一个:
Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);
即使您选择只提供一个实现,您也可能希望使用这样的命名约定来阐明您的契约,并且它有助于您决定添加其他实现。
你不应该过度使用它,但它可能是有帮助的,特别是当你编写一个helper类时,你将在数百个不同的应用程序中使用许多不同的错误处理约定。
使用空对象模式或抛出异常。