【问题标题】:types of expressions in operator ?(expression 1):(expression 2) in Java [duplicate]Java中运算符?(表达式1):(表达式2)中的表达式类型[重复]
【发布时间】:2018-01-12 10:53:21
【问题描述】:

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

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():

方式 1 调用失败。我以为我错过了括号。

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

方式 3 失败。 new String[]{} 是 String[] 对象,为什么 Java 编译器还是看不懂?

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

方式 5 调用成功。

我猜的:

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

谁能对 operator: 有很好的了解?解决我的困惑?谢谢。

【问题讨论】:

标签: java operator-keyword


【解决方案1】:
String a = condition ? "pass" : "fail";

是以下的简写:

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

【讨论】:

    【解决方案2】:

    看起来人们真的不明白你的问题,你可能想编辑它。

    无论如何,这是我的答案:

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

    value = condition ? expression : expression
    

    逗号不是 java 中的运算符,编译器完全期望它是一个运算符。

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

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

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

    【讨论】:

    • 这是我想要的答案。 test(String...) 需要一个变长参数,我可以这样说:test(object) and object = flag?表达式1:表达式2,这就是为什么两个表达式必须返回相同的类型。
    【解决方案3】:

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

    ?: 运算符主要用于简化 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);
    

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

    方式 4

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

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

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

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

    方式 5

    test(flag? str1: str2); 
    

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

    【讨论】:

    • 方式 3 失败,因为三元表达式的两个表达式必须是同一类型。
    • 如果我没记错的话。 c = 真的?一:乙;即使 a 是 int 和 b 字符串也会起作用。
    • 自动装箱适用于原始类型,但对于更复杂的类型,您会看到意想不到的结果。不要养成这样做的习惯。
    • 我猜对于更复杂的类型它只是失败了。是的,我不这样做,只是说并非总是如此。
    【解决方案4】:

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

    通常java中的三元运算符被允许根据条件返回不同类型的值。这是 java 中的有效表达式:

    int anInteger = 1;
    String aString = "a";
    
    System.out.println(true ? anInteger : aString);
    System.out.println(false ? anInteger : aString);
    

    输出为:

    1
    a
    

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

    【讨论】:

    • OP 询问了三元运算符。 Elvis 运算符是三元运算符的简写,您不指定真条件 (false ?: aString)。
    • 你说的是真的。
    猜你喜欢
    • 2013-08-09
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 2023-03-22
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    相关资源
    最近更新 更多