简体   繁体   English

JAVA 8中的NULL安全对象检查

[英]NULL safe object checking in JAVA 8

So i want to do a null safe check on a value contained within a value. 所以我想对值中包含的值进行空值安全检查。

So I have 3 objects contained within each other: 所以我有3个对象包含在彼此之内:

Person has a clothes object which has a country object which has a capital 人具有衣服对象,其具有具有资本的国家对象

So a person may not have clothes so a check like this throws a null pointer: 所以一个人可能没有衣服,所以像这样的支票会抛出一个空指针:

if (person.getClothes.getCountry.getCapital)

How would I make a statement like this just return false if any of the objects on the path are null? 如果路径上的任何对象为空,我将如何创建这样的语句只返回false?

I also don't want to do it this way. 我也不想这样做。 (A one-liner in Java-8 if possible. (如果可能的话,在Java-8中使用单行程序。

if (person !=null) {
    if (person.getClothes != null) {
        if (person.getClothes.getCountry !=null) {
            etc....
        }
    }
}

You can chain all of those calls via Optional::map . 您可以通过Optional::map链接所有这些调用。 I sort of find this easier to read than if/else , but it might be just me 我发现这比if/else更容易阅读,但它可能只是我

Optional.ofNullable(person.getClothes())
        .map(Clothes::getCountry)
        .map(Country::getCapital)
        .ifPresent(...)

These "cascade" null-checks are really paranoid and defensive programming. 这些“级联”无效检查实际上是偏执和防御性编程。 I'd start with a question, isn't better to make it fail fast or validate the input right before it's store into such a data structure? 我从一个问题开始,是不是更好地使它快速失败或在存储到这样的数据结构之前验证输入?

Now to the question. 现在回答这个问题。 As you have used nested the null-check, you can do the similar with Optional<T> and a method Optional::map which allows you to get a better control: 正如您使用嵌套的null-check,您可以使用Optional<T>和一个方法Optional::map执行类似的操作,它允许您获得更好的控件:

Optional.ofNullable(person.getClothes())
        .map(clothes -> clothes.getCountry())
        .map(country -> country.getCapital())
        .orElse(..)                               // or throw an exception.. or use ifPresent(...)

As you mentioned Java -8 Here is what you would like 正如你提到的Java -8这就是你想要的

Objects.isNull(person) //returns true if the object is null

Objects.nonNull(person) //returns true if object is not-null

Optional.ofNullable(person.getClothes())
    .flatMap(Clothes::getCountry)
    .flatMap(Country::getCapital)
    .ifPresent(...)

By using Optional, and never working with null, you could avoid null checks altogether. 通过使用Optional,并且从不使用null,您可以完全避免空值检查。 Since they aren't needed, you also avoid omitting a null check leading to NPEs. 由于不需要它们,您还可以避免省略导致NPE的空检查。 Still, make sure that values returned from legacy code (Map, ...), which can be null, are wrapped asap in Optional. 尽管如此,请确保从遗留代码(Map,...)返回的值(可以为null)在“可选”中包装为asap。 check here 检查一下

if(Objects.nonNull(person) && Objects.nonNull(person.getClothes) &&  Objects.nonNull(person.getClothes.getCountry )){
   // do what ever u want
 }

And if you are operating with Collections and using org.apache.commons then CollectionUtils.isNotEmpty(persons) and CollectionUtils.isEmpty(persons) will works for you. 如果您正在使用Collections并使用org.apache.commons那么CollectionUtils.isNotEmpty(persons)CollectionUtils.isEmpty(persons)将适合您。 Where Persons is List of person. Persons List

You can achieve using single line of code 您可以使用单行代码实现

if (person != null && person.getClothes != null && person.getClothes.getCountry != null) { }

As you know there is substantial difference between = and == . 如您所知, ===之间存在很大差异。

The operators && and || 运算符&&和|| are short-circuiting, meaning they will not evaluate their right-hand expression if the value of the left-hand expression is enough to determine the result 是短路的,这意味着如果左手表达的值足以确定结果,他们就不会评估他们的右手表达

If your first expression is true then only it will check for next expression. 如果您的第一个表达式为true,则只检查下一个表达式。

If first expression is false then it will not check for next expression. 如果第一个表达式为false,则它不会检查下一个表达式。

So as your requirement if person is not null then only check for person.getClothes != null and so on. 因此,如果person不为null,那么只需检查person.getClothes != null等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM