java api设计-NULL或异常
返回空值或从API方法引发异常更好吗 返回空值需要进行所有难看的空值检查,如果不检查返回值,则会导致严重的质量问题 抛出异常会强制用户编写错误条件的代码,但由于Java异常会冒泡并强制调用方代码处理它们,一般来说,使用自定义异常可能是个坏主意(特别是在Java中)java api设计-NULL或异常,java,api,Java,Api,返回空值或从API方法引发异常更好吗 返回空值需要进行所有难看的空值检查,如果不检查返回值,则会导致严重的质量问题 抛出异常会强制用户编写错误条件的代码,但由于Java异常会冒泡并强制调用方代码处理它们,一般来说,使用自定义异常可能是个坏主意(特别是在Java中) 我认为答案完全取决于应用程序的上下文,而你认为是一个“例外情况”,而不是程序员错误。 例如,如果编写XML解析器,您可以选择实现以下方法: /** * Returns first child element with matchin
我认为答案完全取决于应用程序的上下文,而你认为是一个“例外情况”,而不是程序员错误。 例如,如果编写XML解析器,您可以选择实现以下方法:
/**
* Returns first child element with matching element name or else
* throws an exception. Will never return null.
*/
Element getMandatoryChildElement(Element parent, String elementName)
throws MissingElementException;
。。。因为这种方法允许您在单个逻辑块中实现消息解析代码,而无需在检索每个元素或属性后检查消息的格式是否正确。这实际上取决于您希望如何处理这种情况。如果它确实是一个错误条件,那么抛出一个异常。如果null是一个可接受的输出,那么只需记录它并让用户处理它。如果
null
是一个可接受的返回值(即,它可以由有效输入而不是错误情况产生),那么返回null
;否则抛出异常
我完全不理解你的说法,即检查异常可能是个坏主意,因为调用方被迫处理它们——这就是检查异常的全部意义。它可以防止错误条件在未正确处理的情况下传播到代码中。如果存在内部库错误(意外),则让运行时异常传播。如果库代码中有bug,则客户端可能会崩溃。修复库中的错误。不要捕获全部并返回特定于库的异常,这不会有任何好处 如果您希望(有时)出现问题,请将其构建到API中。这是基于您不应该对正常程序流使用异常的原则 例如:
ProcessResult performLibraryTask(TaskSpecification ts)
if (currentPeriod().equals(SmurfColor.BLUE) && SmurfColor.GREEN.equals(taskSpecification.getSmurfColor()) {
throw new IllegalStateException("Cannot search for green smurfs during blue period, invalid request");
}
通过这种方式,您可以让ProcessResult指示错误条件:
ProcessResult result = performLibraryTask(new FindSmurfsTaskSpecification(SmurfColor.BLUE));
if (result.failed()) {
throw new RuntimeException(result.error());
}
这种方法类似于returnnull方法,但您可以将更多信息发送回客户端
编辑:
对于不符合约定协议的交互,您可以抛出运行时错误,您可以记录这些错误。例如:
ProcessResult performLibraryTask(TaskSpecification ts)
if (currentPeriod().equals(SmurfColor.BLUE) && SmurfColor.GREEN.equals(taskSpecification.getSmurfColor()) {
throw new IllegalStateException("Cannot search for green smurfs during blue period, invalid request");
}
请注意,这是由于一次违反合同的互动,预计不会发生 我倾向于将null返回给“getXXX”方法,例如,从数据库中获取某些内容
示例:用户getUserByName(字符串名)可以让我返回null
但是,如果需要通过调用该方法获取的内容,请抛出异常:
例如:getDatabaseConnection()必须始终返回连接,并且永远不返回null
对于返回集合或数组的方法,永远不要返回null。
返回一个空集合/数组,而不是A同意其他集合/数组,若null是可接受的返回值,则返回它,否则不返回
我想补充的是,您还可以区分已检查和未检查的异常。在某些情况下,建议使用未经检查的异常,例如,API的用户可能无法处理该异常。Spring Framework经常使用未经检查的异常,这使得代码通常更易于阅读,但有时更难跟踪错误。Josh Bloch建议返回空对象或“单位”对象来代替空值。查看大量有用的Java花絮。在中,作者建议不要返回
null
value()
他的主要观点是,这导致了针对null
值的检查和更多文档的激增
我还强烈建议阅读该领域权威人士(T.霍尔)的“”一文 我的观点是
永远不要在返回时返回NULL
类型是集合或数组。如果没有返回值,则返回空集合或空数组
这消除了空检查的需要
良好实践:
public List<String> getStudentList()
{
int count = getStudetCount();
List<String> studentList = new ArrayList<String>(count);
//Populate studentList logic
return studentList;
}
public List getStudentList()
{
int count=getStudetCount();
List studentList=新数组列表(计数);
//填充学生列表逻辑
返回学生名单;
}
坏习惯:。永远不要像下面这样写代码
public List<String> getStudentList()
{
int count = getStudetCount();
if(count == 0)
{
return null;
}
//Populate studentList logic
return studentList;
}
public List getStudentList()
{
int count=getStudetCount();
如果(计数=0)
{
返回null;
}
//填充学生列表逻辑
返回学生名单;
}
我通常会查看JDK中的一个类似示例
对于访问器,使用Null是有意义的
Null应用于指示缺少或未知的数据
对于其他方面,它通常表示处理中的错误
现在,我们有两个选项,运行时和编译时。下面是我如何寻找类比的例子
让我们从ArrayIndexOutOfBoundException中提取一个示例。访问或更改元素是一种非常常见的操作
如果它被选中,那么消费代码将非常混乱。另外,一般来说,开发人员倾向于了解可能导致ArrayIndexOutOfBounException的情况,并且可以通过编写好的代码来避免这种情况
另一方面,如果我们有一段代码,比如打开一个文件,这可能是由于外部依赖性(缺少文件或没有足够的特权)造成的,而不是源于程序中的错误,检查异常是个好主意。@danben-我真的不喜欢抛出六个自定义异常的API,我必须添加一堆不相关的异常处理程序。这本身不是问题,但如果API添加了新的异常,则需要更新所有上游链。我能理解所有必要的,甚至是一件好事,但我一直在寻找