Java 检查返回值是否不为null,如果为null,则在一行中用一个方法调用分配它
Java中充斥着如下语句:Java 检查返回值是否不为null,如果为null,则在一行中用一个方法调用分配它,java,syntax,null,variable-assignment,method-call,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() : getFreeRangeChic
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=某个值不为null或其他值时的某个值
价值观
我想我在这里讲的是语法,在编译代码之后,从性能角度看,代码的编写方式可能没有多大区别
由于这是如此常见的代码,所以最好有一行代码来编写它
其他语言有这个功能吗
dinner = cage.getChicken();
if(dinner == null) dinner = getFreeRangeChicken();
或
Java缺少coalesce运算符,因此,使用显式临时变量的代码是使用单个调用进行赋值的最佳选择 您可以使用结果变量作为临时变量,如下所示:
dinner = ((dinner = cage.getChicken()) != null) ? dinner : getFreeRangeChicken();
但是,这很难理解。使用Java 1.8,您可以使用
可选的
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();
}
}
公共类主{
公共静态void main(字符串[]args){
//示例调用时,这些方法只是哑模板,请注意它们是静态的
FutureFine餐=getChicken().orElse(getFreeRangeChicken());
//使用静态方法调用此函数的另一种可能方法是
FutureFine=getChicken().OrelGet(Main::getFreeRangeChicken);//方法引用
//或者,如果您使用Main的一个实例并调用getChicken和getFreeRangeChicken
//作为非静态方法(假设静态将为此替换为public)
Main m=新的Main();
futuremedin-mean=m.getChicken().orElseGet(m::getFreeRangeChicken);//方法引用
//或
FutureFine-Fine=m.getChicken().orElse(m.getFreeRangeChicken());//方法调用
}
静态可选getChicken(){
//不是返回null,而是返回Optional.empty()
//在这里,我只是返回它来演示
返回可选的.empty();
//如果您要返回一个有效的对象,下面的注释就是代码
//futuremedin ret=new futuremedin();//返回对象
//返回可选。of(ret);
}
静态未来餐getFreeRangeChicken(){
返回新的未来餐();
}
}
您将为getChicken
实现一个逻辑,以返回Optional.empty()
而不是null,或者Optional.of(myReturnObject)
,其中myReturnObject
是您的chicken
然后你可以调用getChicken()
,如果它返回可选。empty()
在你的例子中,orElse(fallback)
将为你提供任何回退,第二种方法。或者在Java8中,你可以根据需要使用null或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();
}
}
}
与洛基的答案相同,但更短。只要记住,越短并不意味着越好
dinner = Optional.ofNullable(cage.getChicken())
.orElse(getFreerangeChicken());
注意:JDK的架构师和可选特性的设计者明确反对使用Optional
。您正在分配一个新对象,每次都会立即将其丢弃。但另一方面,它可以非常可读。如果您还没有使用java 1.8,并且不介意使用commons lang,您可以使用
您的代码是:
dinner = ObjectUtils.defaultIfNull(cage.getChicken(),getFreeRangeChicken())
用你自己的
优势
- 如果不使用Java8开发,则可以正常工作
- 适用于android开发,支持API 24之前的设备
- 不需要外部库
缺点
- 始终计算
默认值
(与cond?nonNull()相同:notEvaluated()
)
这可以通过传递一个可调用的值而不是默认值来避免,但会使它变得更加复杂和不那么动态(例如,如果性能是一个问题)
顺便说一句,使用Optional.orElse()
;-)时也会遇到同样的缺点
自Java 9以来,您拥有以下功能:
public static <T> T requireNonNullElse(T obj, T defaultObj) {
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}
它是一行,只调用一次getChicken()
,所以这两个要求都得到了满足
请注意,第二个参数也不能是null
;此方法强制返回值为非空
还可以考虑另一种选择:
public static T requirenornelseget(T obj,supplier不是一个真正的答案,但是如果你的代码中充满了这样的代码块,用默认值替换丢失的值,那么你的API的设计可能会有问题。撇开大括号不谈,在求值中使用赋值不应该是合法的。这段代码太难阅读,也太容易出错。而y回答问题在你的答案中加入一些文字来解释你在做什么总是一个好主意。阅读。我发现答案的第一部分是最好的解决方案,它清晰易懂,并且只调用一次getChicken。为什么不使用java 8?java 8具有可选功能,不需要外部依赖。你仍然可以使用它当然,这是一个很好的答案。例如,当您为Android pre API 24开发时,可选调用不可用。ObjectUtils还提供了firstNonNull(cage.getChicken(),getFreeRangeChicken())
,这在IMO中读起来更好,并且允许更长的回退链。如果getFreeRangeChicken()
代价高昂,请确保使用dinner=Optional.ofNullable(cage.getChicken()).OrelGet(()->getFreerangeChicken());
这在websocket客户端中很有用:javax.websocket.CloseReason.getReasonPhrase()
在成功的消息上返回null
dinner = ObjectUtils.defaultIfNull(cage.getChicken(),getFreeRangeChicken())
public static <T> T defaultWhenNull(@Nullable T object, @NonNull T def) {
return (object == null) ? def : object;
}
defaultWhenNull(getNullableString(), "");
public static <T> T requireNonNullElse(T obj, T defaultObj) {
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}
dinner = Objects.requireNonNullElse(cage.getChicken(), getFreeRangeChicken());
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)