检查返回值是否为空,如果是,则在一行中使用一个方法调用进行分配

Con*_*ty8 48 java syntax null variable-assignment method-call

Java充斥着如下语句:

if(cage.getChicken() != null) {
    dinner = cage.getChicken();
} else {
    dinner = getFreeRangeChicken();
}
Run Code Online (Sandbox Code Playgroud)

getChicken()在返回的对象可以分配之前需要两次调用dinner.

这也可以写成一行,如下所示:

dinner = cage.getChicken() != null? cage.getChicken() : getFreeRangeChicken();
Run Code Online (Sandbox Code Playgroud)

但唉,还有两个电话getChicken().

当然我们可以分配一个局部变量,然后再次使用三元运算符来分配它,如果它不是null,但这是两行而不是那么漂亮:

FutureMeal chicken = cage.getChicken();
dinner = chicken != null? chicken : getFreeRangeChicken();
Run Code Online (Sandbox Code Playgroud)

那么有什么方法可以说:

变量var =某些值,如果某个值不为null或其他值;

我想我只是在这里讨论语法,在编译代码之后,它可能没有太大的区别代码是如何在性能意义上编写的.

因为这是一个很常见的代码,所以有一个单行写入它会很棒.

是否有其他语言有此功能?

jhy*_*yot 59

与Loki的回答相同,但更短.请记住,较短并不会自动意味着更好.

dinner = Optional.ofNullable(cage.getChicken())
  .orElse(getFreerangeChicken());
Run Code Online (Sandbox Code Playgroud)

注意:OptionalJDK的架构师和Optional功能的设计者明确不鼓励这种用法.您正在分配一个新鲜的物体,并且每次都会立即丢弃它.但另一方面它可以很容易阅读.

  • 如果`getFreerangeChicken()`代价很高,请确保使用`dinner = Optional.ofNullable(cage.getChicken()).orElseGet(() - > getFreerangeChicken());` (7认同)
  • @HeatherSawatsky,我认为只是因为,正如本答案的海报所指出的那样,每次使用它时都会分配一个全新的可选对象,因此它比自己检查它是否为空更昂贵。 (3认同)

das*_*ght 52

Java缺少合并运算符,因此具有显式临时值的代码是单个调用的赋值的最佳选择.

您可以将结果变量用作临时变量,如下所示:

dinner = ((dinner = cage.getChicken()) != null) ? dinner : getFreeRangeChicken();
Run Code Online (Sandbox Code Playgroud)

然而,这很难理解.


use*_*551 23

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

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

你的代码是

dinner = Objects.requireNonNullElse(cage.getChicken(), getFreeRangeChicken());
Run Code Online (Sandbox Code Playgroud)

这是 1 条线路并且getChicken()只调用一次,因此满足两个要求。

请注意,第二个参数不能null一样;此方法强制返回值的非空性。

还要考虑替代Objects#requireNonNullElseGet

public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
Run Code Online (Sandbox Code Playgroud)

如果第一个参数不是,它甚至不评估第二个参数null,但确实有创建Supplier.


Pie*_*Bie 14

如果你还没有使用java 1.8并且你不介意使用commons-lang你可以使用org.apache.commons.lang3.ObjectUtils #defaultIfNull

你的代码是:

dinner = ObjectUtils.defaultIfNull(cage.getChicken(),getFreeRangeChicken())
Run Code Online (Sandbox Code Playgroud)

  • ObjectUtils 还提供了``firstNonNull(cage.getChicken(),getFreeRangeChicken())````,在我看来读起来更好,并且允许更长的后备链。 (2认同)

Lok*_*oki 11

使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

您将实现一个逻辑,getChicken以返回或者返回Optional.empty()null,或者Optional.of(myReturnObject),myReturnObject您的位置chicken.

然后你可以打电话getChicken(),如果它会返回Optional.empty(),orElse(fallback)那么就会给你任何后备,在你的情况下是第二种方法.


Lev*_*ite 5

用你自己的

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

例子:

defaultWhenNull(getNullableString(), "");
Run Code Online (Sandbox Code Playgroud)

 

好处

  • 如果您不使用 Java8 进行开发,则可以使用
  • 适用于 Android 开发,支持API 24 之前的设备
  • 不需要外部库

缺点

  • 始终评估default value(与 相反cond ? nonNull() : notEvaluated()

    这可以通过传递一个 Callable 而不是默认值来规避,但使其更复杂和更不动态(例如,如果性能是一个问题)。

    顺便说一句,您在使用时遇到了同样的缺点Optional.orElse();-)