java 检查返回值是否不为null,如果是,则在一行中用一个方法调用分配它

yr9zkbsy  于 2023-05-05  发布在  Java
关注(0)|答案(9)|浏览(110)

Java中充斥着这样的语句:

if(cage.getChicken() != null) {
    dinner = cage.getChicken();
} else {
    dinner = getFreeRangeChicken();
}

在返回的对象可以分配给dinner之前,需要对getChicken()进行两次调用。
这也可以写成这样的一行:

dinner = cage.getChicken() != null? cage.getChicken() : getFreeRangeChicken();

但遗憾的是,仍然有两个对getChicken()的调用。
当然,我们可以赋值一个局部变量,如果它不为null,则再次使用三元运算符赋值,但这是两行,并不那么漂亮:

FutureMeal chicken = cage.getChicken();
dinner = chicken != null? chicken : getFreeRangeChicken();

那么有没有办法说:
变量var =某个值,如果某个值不为空,或者某个其他值;
我想我只是在这里谈论语法,在代码编译之后,从性能的Angular 来看,代码的编写方式可能没有太大的区别。
由于这是如此常见的代码,如果能用一行程序来编写它就太好了。
其他语言有这个功能吗?

5kgi1eie

5kgi1eie1#

和洛基的答案一样但更短。请记住,短并不意味着更好。

dinner = Optional.ofNullable(cage.getChicken())
  .orElse(getFreerangeChicken());

注意:JDK的架构师和Optional特性的设计者明确反对使用Optional。你分配了一个新的对象,每次都立即将其丢弃。但另一方面,它可以相当可读。

2lpgd968

2lpgd9682#

Java缺少合并运算符,因此,对于使用单个调用进行赋值的情况,使用显式临时变量的代码是最佳选择。
你可以使用result变量作为临时变量,如下所示:

dinner = ((dinner = cage.getChicken()) != null) ? dinner : getFreeRangeChicken();

然而,这是很难读懂的。

sgtfey8w

sgtfey8w3#

从Java 9开始,你有了Object #requireNonNullElse,它可以:

public static <T> T requireNonNullElse(T obj, T defaultObj) {
    return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}

你的代码应该是

dinner = Objects.requireNonNullElse(cage.getChicken(), getFreeRangeChicken());

这是1行,并且只调用getChicken()一次,因此这两个要求都得到了满足。
注意,第二个参数也不能是null;此方法强制返回值为非空值。
还可以考虑替代对象#requireNonNullElseGet:

public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)

如果第一个参数不是null,它甚至不计算第二个参数,但确实有创建Supplier的开销。

qcuzuvrc

qcuzuvrc4#

如果不介意使用commons-lang,可以使用org.apache.commons.lang3.ObjectUtils#defaultIfNull
你的代码应该是:

dinner = ObjectUtils.defaultIfNull(cage.getChicken(),getFreeRangeChicken())
bwntbbo3

bwntbbo35#

使用Java 1.8,您可以使用Optional

public class Main  {

    public static void main(String[] args) {

        //example call, the methods are just dumb templates, note they are static
        FutureMeal meal = getChicken().orElse(getFreeRangeChicken());

        //another possible way to call this having static methods is
        FutureMeal meal = getChicken().orElseGet(Main::getFreeRangeChicken); //method reference

        //or if you would use a Instance of Main and call getChicken and getFreeRangeChicken
        // as nonstatic methods (assume static would be replaced with public for this)
        Main m = new Main();
        FutureMeal meal = m.getChicken().orElseGet(m::getFreeRangeChicken); //method reference

        //or
        FutureMeal meal = m.getChicken().orElse(m.getFreeRangeChicken()); //method call

    }

    static Optional<FutureMeal> getChicken(){

        //instead of returning null, you would return Optional.empty() 
        //here I just return it to demonstrate
        return Optional.empty();

        //if you would return a valid object the following comment would be the code
        //FutureMeal ret = new FutureMeal(); //your return object
        //return Optional.of(ret);            

    }

    static FutureMeal getFreeRangeChicken(){
        return new FutureMeal();
    }
}

您可以为getChicken实现一个逻辑,以返回Optional.empty()而不是null,或者Optional.of(myReturnObject),其中myReturnObject是您的chicken
然后你可以调用getChicken(),如果它会返回Optional.empty()orElse(fallback)会给予你任何回退,在你的例子中是第二个方法。

tzcvj98z

tzcvj98z6#

用你自己的

public static <T> T defaultWhenNull(@Nullable T object, @NonNull T def) {
    return (object == null) ? def : object;
}

示例:

defaultWhenNull(getNullableString(), "");

优势

  • 如果你不是用Java8开发的话**
  • 适用于Android开发,支持pre API 24设备
  • 不需要外部库

缺点

  • 始终计算default value(相对于cond ? nonNull() : notEvaluated()

这可以通过传递Callable而不是默认值来规避,但会使其更加复杂和动态性降低(例如如果性能是个问题)。
顺便说一句,在使用Optional.orElse()时,您会遇到同样的缺点;- )

atmip9wb

atmip9wb7#

dinner = cage.getChicken();
if(dinner == null) dinner = getFreeRangeChicken();

if( (dinner = cage.getChicken() ) == null) dinner = getFreeRangeChicken();
xzv2uavs

xzv2uavs8#

或者在Java8中,您可以根据需要使用NullableNotNullAnnotations。

public class TestingNullable {
        @Nullable
        public Color nullableMethod(){
            //some code here
            return color;
        }

        public void usingNullableMethod(){
            // some code
            Color color = nullableMethod();
            // Introducing assurance of not-null resolves the problem
            if (color != null) {
                color.toString();
            }
        }
    }
public class TestingNullable {
        public void foo(@NotNull Object param){
            //some code here
        }

        ...

        public void callingNotNullMethod() {
            //some code here
            // the parameter value according to the explicit contract
            // cannot be null
            foo(null);
        }
    }

http://mindprod.com/jgloss/atnullable.html

tgabmvqs

tgabmvqs9#

你可以用

Objects.requireNonNullElseGet(cage.getChicken(), () -> getFreerangeChicken())

使用static import更好:

import static java.util.Objects.requireNonNullElseGet;

requireNonNullElseGet(cage.getChicken(), () -> getFreerangeChicken())

相关问题