代码之家  ›  专栏  ›  技术社区  ›  Nolesh

Java SE 7——检查嵌套对象为null的最佳方法[复制]

  •  0
  • Nolesh  · 技术社区  · 8 年前

    这个问题已经有了答案:

    据我所知 Java SE 8 有 java.util.Optional<T> 保护代码不受意外影响的类 null 指针异常。但出于某些原因我不得不使用 Java 7 .

    看看我的例子:

    String version = device.getController().version;
    

    最好的检查方法是什么 device 和 getController() 是否为空?

    选项1:

    String version = "unknown";
    if(device!=null){
      if(device.getController()!=null) 
        version = device.getController().version;
    }
    

    选项2:

    String version = "unknown";
    if(device!=null && device.getController()!=null){
      version = device.getController().version;
    }
    

    选项1有点麻烦,但显然它可以正常工作。第二种选择是有问题的,因为我们不知道先检查哪一部分条件以及如何检查 Java 实际上是这样。有一点建议 爪哇 返回结果前检查两部分条件。显然,第二部分会回来 NullPointerException 如果设备为空。那么,检查Java 7和更早的嵌套对象的最好方法是什么?

    4 回复  |  直到 8 年前
        1
  •  1
  •   Stephen C    8 年前

    第二个选项是有问题的,因为我们不知道哪一部分的条件将首先检查,以及Java实际上是如何做的。

    这不是事实。这是一个反事实。

    一个 <expr1> && <expr2> 表达式的计算方法如下:

    1. <expr1> 首先计算。
    2. 如果结果 <表达式1> 是 false ,然后 <expr2> 未计算。表达式的值为 错误 .
    3. 如果结果 <表达式1> 是 true ,然后 <表达式2> 被计算,该值将成为表达式的值。

    以上是一个简化版本。实际规格在 JLS 15.23 .

    但我的观点是 绝对零不确定性 关于如何 && 计算表达式。这是清楚和明确的 每一个 Java版本从Java 1向前…如果您阅读官方规范和/或官方教程。

    选项1和2的功能相同。

    “最好”的方法是意见,但我更喜欢选项2,因为它更简洁,可读性也同样好。(只是我的意见…显然。)

        2
  •  0
  •   k2zinger    8 年前

    选项1和选项2的功能相同

    您可以使用 ternary operator 因为你提到选项1有点“麻烦”

    String version = (device != null && device.getController() != null) ? device.getController().version : "unknown";
    
        3
  •  0
  •   vatbub    8 年前

    您的第二个选项完全有效。Java从左到右评估条件。这意味着它将首先评估 device!=null 然后 device.getController()!=null .

    如果和条件的左侧( device != null 被发现是错误的,Java将不会评估右侧。右侧将只对 设备!=空 .

        4
  •  0
  •   singh30    8 年前

    选项2没有问题,首先检查

    device != null
    

    如果这是错误的,即设备为空,则不会检查

    device.getController()!=null
    

    因为false&&(true/false)是false

    我建议你用“试着抓”的方法。

    String version = null;
    try {
           version = device.getController().version;
         } catch (NullPointerException ex) {
             //log the error here
         }