【问题标题】:How often will a function be called in a ternary operator?在三元运算符中多久调用一次函数?
【发布时间】:2023-01-20 08:43:40
【问题描述】:

我有这行 Java 代码:

return getValue() != null ? getValue() : 0

getValue多久执行一次?一次还是两次?

编辑:如果这是编译器相关的,我对 Sun JDK 的编译器特别感兴趣。

【问题讨论】:

  • 题外话:自动装箱是邪恶的,更喜欢明确的valueOf(0)

标签: java


【解决方案1】:

如果 getValue() == null - 一次

如果 getValue() != null - 两次

【讨论】:

  • 当然,运行时字节码 -> 机器代码编译器(通常是 HotSpot)可能会内联它并进行公共子表达式消除(CSE)。
  • 实际上它不能内联它,因为它可能有副作用,而编译器不知道。
  • JIT 编译器可以知道该方法是否有副作用。问题是它花了多少时间(如果有的话)来测试它。
  • 不,它不知道,至少在 Java 这样的语言中不知道。您必须将每个类中的每个方法标记为无副作用或无副作用,以便 JIT 找出它。而字节码没有这样的信息。
  • 抱歉,那是错误的。虽然我不知道 sun VM 是否这样做,但我已经看到几个 JIT 编译器可以这样做。并找出你的方法是否有副作用不需要任何特殊的字节码支持。例如:如果 getValue() 的实现是 return null;那么确定没有副作用是微不足道的。事实上,在那种情况下,编译器会优化整个 if 结构。
【解决方案2】:

如果 getValue() 返回 null,则仅执行一次,如果第一次返回 null 以外的值,则执行两次。

【讨论】:

    【解决方案3】:

    如果getValue() 返回一个非空值,两次。

    public class Test {
    public static void main(String[] args) {
        Test t = new Test();
        boolean x = t.doSomething()? t.doSomething():false;
    }
    public boolean doSomething(){
        System.out.println("calling doSomething");
        return true;
    }
    }
    

    输出:

    calling doSomething
    calling doSomething
    

    【讨论】:

    • 这可能是一个糟糕的测试。我认为这根本无法优化。如果你只有return true;,它可能会被优化为一个电话。
    • 如果你做“return true”,整个​​表达式可能会被“true”替换,所以它根本不会被调用。
    【解决方案4】:

    清除答案:

    从开发者的角度来看:

    if getValue() == null - 将被调用一次

    if getValue() != null - 将被调用两次

    从 JIT 编译器的角度来看:

    取决于编译器和您的方法。最多调用2次,最少调用0次。

    • 如果不为空则为两倍;编译器不优化;或者该方法有副作用
    • 如果第一次调用 getValue() 总是返回 null 并且没有副作用并且编译器进行了优化,则为零次

    【讨论】:

      【解决方案5】:

      你能重新写一下吗?我不熟悉 Java,但在 C++ 中你可以说

      return (x=getvalue()) != null ? x : 0
      

      如果这在 Java 中行不通,您可以在返回之前移动赋值吗?它需要是单行吗?

      x = getvalue();
      return x != null ? x : 0
      

      约翰 C>

      【讨论】:

        【解决方案6】:

        我有一个与您的问题相关的不同场景。我还想为一个变量设置一个值,该变量是三元运算符的结果,如下所示:

        String thing = something == null ? "the other thing" : getSomethingElse();
        

        那个代码仍然执行"getSomethingElse()" 即使是 "something"无效的。

        似乎三元运算符中的所有函数都在条件评估之前执行——与其他人给出的答案相反。

        【讨论】:

          猜你喜欢
          • 2020-06-18
          • 2021-09-30
          • 1970-01-01
          • 2016-11-21
          • 1970-01-01
          • 1970-01-01
          • 2014-01-19
          • 2017-11-12
          • 2016-07-09
          相关资源
          最近更新 更多