Java 中运算符 ?(表达式 1):(表达式 2) 中的表达式类型

types of expressions in operator ?(expression 1):(expression 2) in Java

我遇到了一个问题,代码如下:

public class Test {

    public static void main(String[] args) {
        String str1 = "1";
        String str2 = "2";
        String str3 = "3";
        boolean flag = true;

        // way 1
        test(flag? str1, str2, str3: str1); 

        // way 2
        test(flag? (str1, str2, str3): str1);

        // way 3
        test(flag? new String[]{str1, str2, str3}: str1);

        // way 4
        test(flag? new String[]{str1, str2, str3}: new String[]{str1});

        // way 5
        test(flag? str1: str2);  
    }

    private static void test(String... args) {
        for(String arg: args) {
            System.out.println(arg);
        }
    }

}

我用了五种方法调用方法test():

方法一调用失败。我以为我漏掉了括号。

方式2失败。我以为是(str1, str2, str3)的问题,Java编译器没看懂

方式三失败。 new String[]{} 是一个 String[] 对象,为什么 Java 编译器还是不理解它?

方式4成功。冒号的左右参数是同一类型。所以,我用方法5来调用它。

方式5调用成功

我猜的:

     ?(1):(2), the parameters in place 1 and 2 must be the same type?

谁能对运算符有很好的理解:?解决我的困惑?谢谢。

String a = condition ? "pass" : "fail";

是 shorthand 用于:

String a;
if ( condition ) {
  a = "pass";
} else {
  a = "fail";
}

它被称为“三元运算符”。更多信息在这里: ?: on Wikipedia.

通常 java 中的三元运算符根据条件允许 return 不同类型的值。这是 java:

中的有效表达式
int anInteger = 1;
String aString = "a";

System.out.println(true ? anInteger : aString);
System.out.println(false ? anInteger : aString);

输出为:

1
a

另一方面,在您的代码段中,returned 值作为参数传递给以 String... 作为参数的测试方法。所以 returned 值应该匹配那个类型。

我不能说我有深刻的理解。不过我还是会尽力解释的。

?: 运算符基本上用于简化 if else 表达式

if (a > b) {
  c = a;
}
else {
  c = b;
}

这可以写成c = (a > b) ? a : b;

现在,在方式 1

test(flag? str1, str2, str3: str1); 

编译器失败是因为它期望在 str1 之后是 : 而不是 , 这就是它失败的原因。

现在方式2

test(flag? (str1, str2, str3): str1);

(str1,str2,str3) 不是有效对象。您必须创建一个数组来存储一组字符串。简单地将它们捆绑在 () 中是行不通的。

方式 3

test(flag? new String[]{str1, str2, str3}: str1);

现在我认为失败的原因是因为测试需要字符串数组输出,但 str1 只是一个字符串。

方式 4

test(flag? new String[]{str1, str2, str3}: new String[]{str1});

这会成功执行,但仅仅像这样切换会导致输出失败。

test(flag? new String[]{str1}: new String[]{str1, str2, str3});

因为测试需要一个字符串数组作为输出。 但是编译成功,因为它们都是字符串数组。

方式 5

test(flag? str1: str2); 

这是我之前关于期望 String[] 的测试推理失败的地方。 但是即使编译成功,您也不会得到输出,因为测试仍然期望输出数组。

看来人们真的没有理解您的问题,您可能需要对其进行编辑。

无论如何这是我的答案:

方法 1 和方法 2:语法没有意义,您要求编译器做它不能做的事情。三元表达式必须如下所示:

value = condition ? expression : expression

逗号不是 java 中的运算符,编译器正是期望它是运算符。

方法 3:失败,因为三元表达式的两个可能结果必须具有相同的类型。这就是方法 4 工作正常的原因。

方法 5:编译正常,但无法工作,因为您的构造函数仍然需要一个数组。

编辑:我还应该提到,如果您的条件验证为假,方法 4 也会因 ArrayIndexOutOfBoundsException 而失败,但这对您的问题来说微不足道。