在Java的三元运算符中,即使表达式导致假值,是否可以计算第一个参数?
我最近通过随机临时测试在我的代码中发现了一个不寻常的错误。所以,我为它做了一个测试用例。
这是我的测试用例:
SampleRequest request = new SampleRequest();
request.setA(null);
request.setB(null);
assertEquals(null, request.getAOrB());
A 和 B 被定义为 java.lang.Integer 类型,并具有直接 setter 方法将它们的值设置到请求中。
还涉及枚举。它具有一个基元整数值,以及此代码中使用的方法。我将在这里发布相关部分:
enum Swapper {
public int c;
Swapper findSwapperToUse(final int a) {
for(Swapper swapper : values()) {
if(swapper.c == a) {
return swapper;
}
}
return null;
}
}
现在,这是令人困惑的方法。在此方法上调用测试方法会导致 NPE,但在方法的最后一行。
public class SampleRequest {
private Integer A;
private Integer B;
public void setA(final Integer A) {
this.A = A;
}
public void setB(final Integer B) {
this.B = B;
}
public Integer getAOrB() {
return A != null ? Swapper.findSwapperToUse(A).c
: B;
}
}
在测试中,A 和 B 都设置为 null。因此,A != null 返回 false。但是,我在:B行的行号处得到一个NullPointerException。
我的猜测是,由于某种原因,第一个表达式Swapper.findSwapperToUse(A).c正在被计算,因此A.intValue()是通过自动装箱调用的,导致空值上的NullPointerException。通过调试,可以知道不会调用 findSwapperToUse()。
但是,根据这个问题,这不应该发生:Java三元(立即如果)评估
未选择的操作数表达式不会针对条件表达式的特定计算进行计算。
返回 null (B) 不会导致 NullPointerException - 在此处返回 null 结果完全没问题。
这到底是怎么回事?
编辑:我忘了补充一点,我通过使用直接的if语句来更改代码以避免这种情况 - 以下代码确实按预期工作:
public Integer getAOrB() {
if(A != null) {
return Swapper.findSwapperToUse(A).c;
}
return B;
}