【问题标题】:java.util.Objects.isNull vs object == nulljava.util.Objects.isNull vs object == null
【发布时间】:2016-10-24 16:19:49
【问题描述】:

如你所知,java.util.Objects

该类由用于操作对象的静态实用方法组成。

其中一种方法是Objects.isNull()

我的理解是Objects.isNull() 会通过省略第二个= 来消除意外为对象分配空值的机会。

但是,API 说明指出:

此方法的存在是为了用作谓词,filter(Objects::isNull)

是否有任何理由/情况我应该在 if 语句中使用 object == null 而不是 Objects.isNull()

Objects.isNull() 是否应该仅限于谓词?

【问题讨论】:

  • 如果您担心的只是意外分配,您可以简单地使用if(null == variable) 一贯...
  • @Holder,有什么意外分配需要担心?这是Java。你会得到一个类型错误。
  • @LouisWasserman 如果variableBoolean,则不是。
  • @AlexisC,在极小的情况下,这将是一个问题:你的变量必须是一个非常具体的类型,并且 你必须打一个非常具体的错字,并且你不能使用任何 IDE 或编译器分析来为你指出这一点(就像几乎所有 IDE 一样)。我很放心不用担心那个案子。
  • 在工作中,我见过很多 null==object 的实例。当我询问时,我被告知这是为了防止意外的空分配。根据此处提供的 cmets 和答案,我倾向于认为这是一个品味问题。

标签: java java-8 compare


【解决方案1】:

是否应该在 if 语句中使用 object == null 而不是 Objects.isNull()?

如果你查看source codeIsNull 方法,

 /* Returns true if the provided reference is null otherwise returns false.*/

 public static boolean isNull(Object obj) {
     return obj == null;
 }

是一样的。没有区别。这样您就可以放心使用了。

【讨论】:

  • 是的,可以使用,但可能会干扰工具执行的本地流量分析。即,使用简单的“==”,任何流分析都可以看到取消引用在 then 分支中不好,但在 else 分支中是安全的。你会得到适当的错误/警告或什么都没有。间接调用 isNull() 时,工具可能会丢失知识。
  • 性能略有不同。 Java 检查对象空引用与调用静态方法会有所不同。而且它比我们都习惯使用的 == 读起来略显不清晰。
  • if 中更多地使用== null 语义,但isNull 非常适合用于lambda 表达式。
  • 这当然是合法的,但对运营商没有任何好处。所以如果你在一个团队中工作,请根据他们的预期目的使用东西。
【解决方案2】:

Objects.isNull 旨在用于 Java 8 lambda 过滤。

写起来更容易更清晰:

.stream().filter(Objects::isNull) 

比写:

.stream().filter(x -> x == null).  

但是,在if 语句中,任何一个都可以。 == null 的使用可能更容易阅读,但最终归结为风格偏好。

【讨论】:

  • 我不同意“写起来更容易/更清晰”的说法。 1. 不够简洁。 2. 它的表达力明显较差,尤其是对于那些不熟悉最新 Java 语法的人。对于我作为一个不每天编写 Java(我编写 Scala)的人来说,拥有一个除了检查 null 之外什么都不做的静态方法感觉很幻觉。这种方法只是对流畅的代码阅读的干扰,没有添加任何好处。
【解决方案3】:

看源码:

public static boolean isNull(Object obj) {
    return obj == null;
}

要检查null 值,您可以使用:

  • Objects.isNull(myObject)
  • null == myObject // avoids assigning by typo
  • myObject == null // risk of typo

Objects.isNull 用于Predicates 的事实并不妨碍您像上面那样使用它。

【讨论】:

  • 错字风险是什么意思?
  • @AshishLohia 使用 = 而不是 == (除非它是一个可以为空的 Boolean 包装器,否则不会编译,你是公平的)
  • 如果 (myObject = null) 会导致编译错误,拼写错误的风险是 C++ 中的问题而不是 Java 中的问题。您应该始终使用 myObject == null 而不是 null == myObject。
  • @TomasMarik 正如我在评论中提到的那样,拼写错误的风险仅限于 Java 中可空的 Boolean 包装器。这确实非常罕见(并且当检查分配给null 时会发出编译器警告,就好像它是一个条件一样),但并非不可能。
【解决方案4】:

if 语句中我应该使用 object == null 而不是 Objects.isNull() 是否有任何原因/情况?

是的,原因之一是保持代码简单。在 if 语句 中,object == null 是清晰且众所周知的。如果有错别字,也不会导致任何不当行为。

我的理解是 Objects.isNull() 会通过省略第二个 = 来消除意外为对象分配空值的机会。

如果有一个if (object = null) {} 省略 =,它将无法编译,否则会在Boolean 对象的情况下生成警告!实际上,没有理由在 if 语句 中使用 Objects.isNull(object) 而不是 object == null。以下是并列的两个变体:

if (object == null) {
}

if (Objects.isNull(object)) {
}

Objects.isNull() 是否应该仅限于 Predicates?

可以说是的,它仅限于谓词,尽管在任何地方使用 Objects.isNull() 没有技术障碍。

来自public static boolean isNull(Object obj) 方法的javadoc:

@apiNote这个方法的存在是为了用作java.util.function.Predicate, filter(Objects::isNull)

因此,如果您将方法用作而不是谓词,那么与简单的object == null 相比,您实际上使用的是更复杂、更麻烦的表达式。

这里有一个sn-p来比较Objects.isNull(object)的好处

List<String> list = Arrays.asList("a", "b", null, "c", null);

// As ready-made predicate
long countNullsWithPredicate = list.stream().filter(Objects::isNull).count();

// Lambda
long countNullsWithLambda = list.stream().filter(object -> object == null).count();

// Reimplement the Objects::isNull predicate
long countNullsWithAnonymous = list.stream().filter(new Predicate<Object>() {
    @Override
    public boolean test(Object obj) {
        return obj == null;
    }
}).count();

【讨论】:

    【解决方案5】:

    语义上没有区别,但为了便于阅读,我更喜欢以下 whatever == null

    import static java.util.Objects.isNull;
    
    // Other stuff...
    
    if(isNull(whatever)) { 
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-31
      • 2016-08-30
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多