Met*_*002 13 java ternary-operator
我最近通过随机ad-hoc测试在我的代码中发现了一个不寻常的错误.所以,我为它做了一个测试用例.
这是我的测试用例:
SampleRequest request = new SampleRequest();
request.setA(null);
request.setB(null);
assertEquals(null, request.getAOrB());
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这是令人困惑的方法.在该方法上调用测试方法会导致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;
}
}
Run Code Online (Sandbox Code Playgroud)
在测试中,A和B都设置为null.因此,A!= null返回false.但是,我在:B行的行号处得到NullPointerException.
我的猜测是由于某种原因,正在评估第一个表达式Swapper.findSwapperToUse(A).c,因此通过自动装箱调用A.intValue(),导致null值出现NullPointerException.通过调试,已知不调用findSwapperToUse().
但是,根据这个问题,这不应该发生: Java三元(即时)评估
未针对条件表达式的特定评估评估未选择的操作数表达式.
返回null(B)不会导致NullPointerException - 在这里返回null结果是完全正常的.
到底他妈发生了什么?
编辑:我忘了添加,我通过使用直接if语句来改变代码以避免这种情况 - 以下代码确实按预期工作:
public Integer getAOrB() {
if(A != null) {
return Swapper.findSwapperToUse(A).c;
}
return B;
}
Run Code Online (Sandbox Code Playgroud)
axt*_*avt 22
我猜这个问题是由于编译器推断出整个表达式的类型
A != null ? Swapper.findSwapperToUse(A).c : B
Run Code Online (Sandbox Code Playgroud)
作为int
离型Swapper.c
,并因此尝试应用解包转换到B
.
- 否则,如果第二个和第三个操作数具有可转换(第5.1.8节)到数字类型的类型,则有几种情况:
- ...
- 否则,二进制数字提升(第5.6.2节)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型.请注意,二进制数字促销执行拆箱转换(第5.1.8节)和值集转换(第5.1.13节).
您可以通过添加以下强制转换来阻止它:
A != null ? (Integer) Swapper.findSwapperToUse(A).c : B
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4610 次 |
最近记录: |