Java 如何正确处理可能的空值?

Java 如何正确处理可能的空值?,java,nullpointerexception,Java,Nullpointerexception,在阅读几个不同的API代码时,我发现它们以不同的方式处理可能的空值。在stackoverflow这里,我读了一些建议,比如不需要显式检查,或者检查并抛出一些有意义的完全异常……等等 假设方法是这样的: public void runThis(SomeObject obj){ ## null handling code comes here ## obj.doSomething() <- possible NPE } 2.引发自定义异常 if(obj==null){ throw

在阅读几个不同的API代码时,我发现它们以不同的方式处理可能的空值。在stackoverflow这里,我读了一些建议,比如不需要显式检查,或者检查并抛出一些有意义的完全异常……等等

假设方法是这样的:

public void runThis(SomeObject obj){
  ## null handling code comes here ##
  obj.doSomething() <- possible NPE
}
2.引发自定义异常

if(obj==null){
 throw new CustomException("Null not allowed here");
}
3.使用断言(只见过一次)

4.什么都不做,java在调用doSomething()时会抛出它。


是否有一些通用的最佳解决方案?

这取决于您从哪里获得了obj,以及您计划如何使用它

  • 应使用异常检查用户输入中的无效值,以及传递给公共/受保护方法的无效值。
    这是为了确保您的方法可以安全地执行,并在无法执行时提供有用的消息。为此目的使用自定义异常

  • 断言应该用于检查您认为应该始终正确的事情。它们是查找代码中错误的工具,因为它们通常在发布版本中被禁用。
    断言最常见的用法是在测试中

是否有一些通用的、最好的解决方案

这是因为
null
没有一个普遍认同的含义。它可能是错误的结果,表示缺少数据,或表示默认值

以下是一些提示:

  • 如果(x==null)无处不在,则比写入
    要好
  • fast失败是好的,所以如果遇到意外的null,请抛出异常
    NullPointerException
    正常,
    IllegalArgumentException
    也正常。自行车棚应该漆成黑色
  • 不要使用断言-这是一个死气沉沉的语言特性
  • 不要屏蔽空值(就像忽略错误一样)

如果您正在寻找一种一劳永逸地解决null问题的解决方案,我想借此机会推广一种编程语言,它能很好地解决这一问题。空值问题基本上在Kotlin中消失了,但同时很容易从Java迁移。

为了便于文档编制,有注释
@nullable
@nonNull
,可用于单个参数。这些参数不会影响逻辑,但会在使用
null
参数调用IDE时向IDE发出提示。所以开发人员可以在正手时调整他们的代码。您展示的所有作品的示例,我个人喜欢三元运算符空检查。例如String name=givenName==null?“无姓名”:姓名;你已经得到了NPE。无论发生什么,都应该是特定于域的:如果它是一个参数,那么您可以检查它并抛出一个非法参数。如果是无效状态,则可能是非法状态异常。如果它是可恢复的,或者它们没有捕捉到意义,那么将出现特定于应用程序的异常。TL;DR:这在很大程度上取决于实际需求,而且通常是一个意见问题。@N247的建议很好。注释做得最好在Objects类中,您可以找到一个@requirennull()方法来根据需要获取非空对象。如果“API”指的是远程调用的REST API,那么您将(我希望)验证输入。进行显式空检查是很有用的,因为从客户机的角度来看,他们经常做的是“忘记在消息中提供字段”,而不是“传递空”。此外,服务器端堆栈跟踪无法帮助他们诊断错误。
if(obj==null){
 throw new CustomException("Null not allowed here");
}
assert obj!=null
//