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

时间:2015-04-09 11:45:53

标签: java syntax null variable-assignment method-call

Java充斥着如下语句:

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

在将返回的对象分配给getChicken()之前,需要对dinner进行两次调用。

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

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

但是仍有两次拨打getChicken()

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

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

有什么方法可以说:

  

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

我想我只是在这里谈论语法,在编译代码之后,它可能不会在性能意义上如何编写代码。

由于这是一个非常常见的代码,因此有一个单行代码可以写它。

其他任何语言都有此功能吗?

9 个答案:

答案 0 :(得分:52)

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

Optional

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

答案 1 :(得分:44)

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

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

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

然而,这很难理解。

答案 2 :(得分: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();
    }
}

您要为getChicken实现逻辑,以返回Optional.empty()而不是null,或Optional.of(myReturnObject),其中myReturnObject是您的chicken

然后你可以致电getChicken(),如果它会返回Optional.empty(),那么orElse(fallback)将为你提供任何后备,在你的情况下是第二种方法。

答案 3 :(得分:11)

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

您的代码将是:

onLayout

答案 4 :(得分:1)

使用您自己的

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()时会遇到同样的缺点; - )

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

或者在Java8中,您可以根据需要使用 Nullable NotNull 注释。

 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

答案 7 :(得分:0)

自Java 9以来,您拥有Objects#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;此方法强制返回值不为空。

还要考虑替代方法Objects#requireNonNullElseGet

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

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

答案 8 :(得分:0)

怎么样?

dinner = cage.getChicken();

if(dinner == null) {
    dinner = getFreeRangeChicken();
}

此方法删除了else部分。