Java 如何编写NullPointerException安全方法和表达式?

Java 如何编写NullPointerException安全方法和表达式?,java,exception,nullpointerexception,Java,Exception,Nullpointerexception,NullPointerException始终是一个代码混乱者。需要检查是否每个对象都是空安全的,并且不抛出NPE 我遇到了一种情况: public void aMethod(Employee emp){ String fullEmployeeDetailRow = "Name: "+emp.getName().getFirstName() +"LastName :"+emp.getName().getFirstName() +"Address:" +emp.ge

NullPointerException
始终是一个代码混乱者。需要检查是否每个对象都是空安全的,并且不抛出NPE

我遇到了一种情况:

 public void aMethod(Employee emp){
     String fullEmployeeDetailRow = "Name: "+emp.getName().getFirstName()
     +"LastName :"+emp.getName().getFirstName()
    +"Address:"
  +emp.getAddress().getBillingAddress().getBuildingNumber().getApartmentNumber()
  +" "    
  +emp.getAddress().getBillingAddress().getStreetName()
  }
在上面的例子中,NPE有很多可能性。例如在

emp.getAddress().getBillingAddress().getBuildingNumber().getApartmentNumber() 
表达,呼叫

getAddress() or getBillingAddress() or getBuildingNumber() 
任何可能为空且可能为NPE源。所以我现在需要整理我的代码,检查每个代码是否可以为空

我的问题/想法是:Java中是否有一种方法可以创建一个方法,该方法接受表达式并计算它是否抛出
NullPointerException
,如果是,则返回一个默认值,比如一个空白的

所以在这种情况下,我需要一个方法

expression=emp.getAddress().getBillingAddress().getBuildingNumber().getApartmentNumber()

问题是,当我尝试创建这样一个方法,并向其传递一个表达式时,Java会在调用该方法之前对该表达式求值,而NPE会事先抛出


如何将表达式传递给方法,并要求Java仅在方法内部对其求值?

在这种情况下,您可以使用Optional

Option.ofNullable(emp)
      .map(e -> e.getAddress())
      .map(a -> a.getBillingAddress())
      .map(a -> a.getBuildingNumber())
      .map(n -> n.getApartmentNumber())
      .orElse("not set")
NullPointerException始终是一个代码簇

我不同意

需要检查是否每个对象都是空安全的,并且不抛出NPE

这不一定是真的。通常情况下,如果NPE试图使用的某个引用意外地为
null
,那么允许从方法中抛出NPE是最合理的做法。当然,标准库在许多地方都采用这种方法。“需要”验证每个引用是否为非空的最可能的原因是外部强加的人为标准

我的问题/想法是,在Java中是否有一种方法可以创建一个方法,该方法接受一个表达式并计算它是否抛出NullPointerException,如果是,则返回一个默认值,即blank“”

我不想说这是不可能的,但肯定没有一种简单的方法可以编写您描述的通用方法。Java没有规定在运行时评估Java源代码。此外,还有什么意义?您可以在
try
块中执行代码,而不是调用这样的方法;如果它抛出了一个NPE,那么抓住它,然后适当地处理这种情况。无需对表达式进行预测试

如何将表达式传递给方法,并要求Java仅在方法内部对其求值

你不能。或者至少,正如我已经说过的,Java没有为它做任何准备。在调用该方法之前,将对用作方法参数的任何表达式求值,并将结果的副本传递给该方法。同样,使用<代码>尝试/<代码> catch < /代码> -几乎可以考虑的任何其他事情都要复杂得多,成本也更高。


或者,也有一些方法,比如@PeterLawrey的方法,可以使测试每一个引用更容易、更美观。这不是你要的,但也许适合你。

谢谢。我们将探索Java8的这一特性。在Java 8之前的版本中是否有类似的解决方案?根据您的回答,本文正确地提出了我的问题,也给出了您的答案@supernova可能有支持此功能的库,但是如果没有lambdas,此代码将更加冗长。为什么不在初始化表达式的地方创建try块?@Dimi这正是我试图避免的。我试图避免在主代码中检查表达式,以避免Null check/NPE代码混乱,并希望将try/catch检查移到单独的checkForNPE()方法。因为在同一个地方可以有许多这样的表达式(参见我的示例),只需将检查代码的任务委托给checkForNPE(),并对所有表达式重用即可。
Option.ofNullable(emp)
      .map(e -> e.getAddress())
      .map(a -> a.getBillingAddress())
      .map(a -> a.getBuildingNumber())
      .map(n -> n.getApartmentNumber())
      .orElse("not set")