gpt4 book ai didi

java - 在 Java 的三元运算符中,即使表达式结果为假值,是否可以计算第一个参数?

转载 作者:搜寻专家 更新时间:2023-10-30 19:54:48 25 4
gpt4 key购买 nike

我最近通过随机临时测试在我的代码中发现了一个不寻常的错误。所以,我为它做了一个测试用例。

这是我的测试用例:

 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 ternary (immediate if) evaluation

The operand expression not chosen is not evaluated for that particular evaluation of the conditional expression.

返回 null (B) 不会导致 NullPointerException - 在这里返回 null 结果完全没问题。

这到底是怎么回事?

编辑:我忘了补充一点,我通过使用直接的 if 语句更改了代码以避免这种情况 - 以下代码确实按预期工作:

public Integer getAOrB() {
if(A != null) {
return Swapper.findSwapperToUse(A).c;
}
return B;
}

最佳答案

我猜这个问题是由编译器推断整个表达式的类型引起的

A != null ? Swapper.findSwapperToUse(A).c : B

作为 Swapper.c 类型的 int,因此尝试将拆箱转换应用于 B

这是来自 the JLS, §15.25 的相关摘录:

  • Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
    • ...
    • Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13).

您可以通过添加以下强制转换来阻止它:

A != null ? (Integer) Swapper.findSwapperToUse(A).c : B

关于java - 在 Java 的三元运算符中,即使表达式结果为假值,是否可以计算第一个参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4923659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com