【问题标题】:Why is the Ternary operator not working inside a method argument in java为什么三元运算符不在java中的方法参数中工作
【发布时间】:2018-03-26 19:46:50
【问题描述】:

我在开发过程中注意到了这一点。

为什么三元运算符在方法参数中不起作用?这里显然是InputStream 或(否则)String

class A{

    public  static boolean opAlpha(InputStream inputStream) {

        // Do something

        return true;

    }

    public static boolean opAlpha(String arg) {

        // Do something else

        return true;
    }

    public static void main(String[] args) throws Exception {

        boolean useIsr = true;

        InputStream inputStream = null;
        String arg = null;

//      boolean isTrue = useIsr ? A.opAlpha(inputStream): A.opAlpha(arg); // This is OK.
        boolean isTrue =  A.opAlpha(useIsr ? inputStream : arg); // This is not. (Error : The method opAlpha(InputStream) in the type A is not applicable for the arguments (Object))

    }

}

【问题讨论】:

  • 这里没有运算符重载。
  • 还有我一贯的迂腐评论:这不是三元运算符,而是conditional operator。确实它是 a 三元运算符(一个接受三个操作数的运算符),而且它确实是 Java 唯一的一个,但理论上在某些时候可能还有其他运算符...... :-)
  • 谢谢 T.J.明白了!

标签: java ternary-operator


【解决方案1】:

编译器需要决定它应该在您的main 方法中调用哪个重载方法。方法调用必须放在main的编译字节码中,而不是在运行时决定。

事实上,即使知道条件表达式的类型是InputStreamString,编译器仍将其类型视为Object。来自Section 15.25.3 of the Java Language Specification

如果引用条件表达式出现在赋值上下文或调用上下文中(第 5.2 节、第 5.3 节),则它是一个多边形表达式。否则,它是一个独立的表达式。

如果多引用条件表达式出现在目标类型为 T 的特定类型的上下文中,它的第二个和第三个操作数表达式同样出现在目标类型为 T 的相同类型的上下文中。

poly 引用条件表达式的类型与其目标类型相同。

独立引用条件表达式的类型确定如下:

  • 如果第二个和第三个操作数的类型相同(可能是空类型),那么就是条件表达式的类型。

  • 如果第二个和第三个操作数之一的类型是空类型,而另一个操作数的类型是引用类型,那么条件表达式的类型就是那个引用类型。

  • 否则,第二个和第三个操作数分别为 S1 和 S2 类型。令 T1 为对 S1 应用装箱转换产生的类型,令 T2 为对 S2 应用装箱转换产生的类型。条件表达式的类型是对 lub(T1, T2) 应用捕获转换(第 5.1.10 节)的结果

其中lub(T1, T2) 代表"Least Upper Bound" 类型T1T2InputStreamString 的最小上限类型是 Object

【讨论】:

  • 谢谢你。您的回答内容丰富,我坚信 SOF 必须可以选择接受多个答案
【解决方案2】:

表达式useIsr ? inputStream : argObject 类型,因为这是inputStream (InputStream) 和arg (String) 的常见类型。

您没有任何接受ObjectopAlpha 方法。因此编译错误。

【讨论】:

  • @Namalak That means it is because it calls the methods depending on the Class type. Not the object type。我不知道你那是什么意思。如果您的意思是它根据参数的编译时类型而不是运行时类型调用方法,那么您是正确的。编译器在编译时决定将调用该方法的哪个重载版本。
  • 那是真正的伊兰。暂时忘记了一般的方法重载原则。一旦我注意到这一点,我就删除了我的评论。删除时我没有注意到您的评论。既然你已经回复了,我会尝试让它再次显示。无论如何,谢谢你的回答。它清除了我!
猜你喜欢
  • 1970-01-01
  • 2013-05-28
  • 2013-04-11
  • 2015-10-07
  • 2017-03-24
  • 1970-01-01
  • 2019-01-04
  • 2019-10-04
相关资源
最近更新 更多