Java - if-else 和三元运算符之间的不同行为

标签 java if-statement conditional-operator

最近我发现 if-else 和三元运算符之间有一个奇怪的行为差异。

我将使用下面的单元测试代码来说明差异。

public class SomeTest {

    @Test
    void testWithTernary_resultIsLong() {
        final SomeClass someClass = new SomeClass();
        assertTrue(someClass.getNumberWithTernary() instanceof Long);
        assertFalse(someClass.getNumberWithTernary() instanceof Integer);
    }

    @Test
    void testWithIfElse_resultIsInteger() {
        final SomeClass someClass = new SomeClass();
        assertTrue(someClass.getNumberWithIfElse() instanceof Integer);
        assertFalse(someClass.getNumberWithIfElse() instanceof Long);
    }

    private static class SomeClass {

        public Object getNumberWithTernary() {
            final long l = this.getLong();
            return (l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE) ? Math.toIntExact(l) : l;
        }

        private long getLong() {
            return 10L;
        }

        public Object getNumberWithIfElse() {
            final long l = this.getLong();
            if (l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE) {
                return Math.toIntExact(l);
            } else {
                return l;
            }
        }
    }
}

以上两个测试均成功。

上面声明的类与我在工作中遇到的代码相比过于简化。

主要方法返回 Object ,并且该方法需要尽可能返回一个整数(即在整数范围内),以便于上游消费。

一开始我用的是三元运算的方法,没想到会有意想不到的效果,直到做了冒烟测试。

任何人都可以解释为什么 if-else 和三元运算符的行为在这种情况下不同吗?

最佳答案

让我们分析一下你的三元表达式 (...) ? Math.toIntExact(l) : l

条件并不重要。第二个操作数(“then”部分)的类型为int。第三个运算符(“else”部分)的类型为long

您可以阅读 Java 语言规范 15.25。条件运算符 ? :精确的规则。但基本上所有数字操作数都被转换为“最宽”类型,因为表达式结果必须具有单一类型,不能返回“longint”,Java类型系统不够强大(有些语言实际上可以做到这一点)。

所以基本上编译器将该表达式重写为以下表达式:

(...) ? ((long) Math.toIntExact(l)) : l

为了将 long 转换为 Object,编译器插入自动装箱调用:

Long.valueOf((...) ? ((long) Math.toIntExact(l)) : l)

这就是您为何会看到此行为的粗略解释。

普通 if 语句无法返回值,因此它仅返回您在 return 语句中指定的任何内容,而无需进一步的数字提升。

关于Java - if-else 和三元运算符之间的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61625201/

相关文章:

java - 提交时出现编译错误 - UVA

java - 使用 Windows 资源管理器上传文件

r - mutate 中的嵌套 ifelse 会产生错误的输出

excel - 数据透视表显示值,而不是值的总和

c - printf 中的三元运算符

php - Mako 中使用 Pylons 的条件运算符

java - Android ArrayList 到 ListView 用于搜索 Activity

java - Java Interposer 中的堆栈粉碎

java - 我不断从方法中得到零

javascript - Node js中的三元函数返回Nan