-2

I met a problem, code like this:

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);
        }
    }

}

I used five ways to call method test():

way 1 called failed. I thought I missed the parentheses.

way 2 failed. I thought it's the problem of (str1, str2, str3), Java compiler didn't understand it.

way 3 failed. new String[]{} is a String[] object, why Java compiler still didn't understand it?

way 4 successfully. the left and right parameter of colon is the same type. So, I called it in way 5.

way 5 called successfully.

I guessed:

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

Can anyone who have a good understanding of operator :? solve my confusion? Thank you.

4 Answers4

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

Is shorthand for:

String a;
if ( condition ) {
  a = "pass";
} else {
  a = "fail";
}
Stultuske
  • 9,296
  • 1
  • 25
  • 37
0

It is called the "ternary operator". More info here: ?: on Wikipedia.

Usually the ternary operator in java is allowed to return different types of values depending on the condition. This is a valid expression in java:

int anInteger = 1;
String aString = "a";

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

with an output of:

1
a

On the other hand, in your piece of code the returned value is being passed as argument to the test method which takes String... as a parameter. So the returned value should match that type.

dbl
  • 1,109
  • 9
  • 17
  • 1
    OP asked about ternary operators. Elvis operators are shorthand for ternary operators where you do not specify the true condition, (false ?: aString). – apexlol Jan 12 '18 at 12:20
  • What you are saying is true though. – dbl Jan 12 '18 at 13:13
0

I can't say I have a deep understanding. But I will try to explain anyway.

?: operator is basically used to simplify the if else expression

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

This can be written as c = (a > b) ? a : b;

Now,in way 1

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

The compiler fails because it is expecting a : instead of the , after str1 which is why it fails.

Now in way 2

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

(str1,str2,str3) is not a valid object. You have to create an array to store a set of strings. Simply bundling them up in () wont work.

Way 3

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

Now I believe the reason for this failing is because test expects a string array output but str1 is only a string.

Way 4

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

This executes successfully but merely switching like so will lead to a failed output.

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

Since test expects a string array as output. But compilation is successfull since both of them are string arrays.

Way 5

test(flag? str1: str2); 

This is where my earlier reasoning of test expecting a String[] fails. But even though compilation will be successful, you wouldn't be getting an output since test is still expecting an array to output.

0

Looks like people really didn't understand your question, you might want to edit it.

Anyway here is my answer:

Method 1 & Method 2: syntax doesn't make sense, you're asking the compiler to do something it cannot. A ternary experssion must look like this:

value = condition ? expression : expression

a comma is not an operator in java and the compiler expects exactly that, an operator.

Method 3: fails because both possible results of a ternary expression must have the same type. Which is why Method 4 works fine.

Method 5: compiles fine, but will not work because your constructor expects an array still.

EDIT: I should also mention that if your condition validates false, Method 4 will also fail with ArrayIndexOutOfBoundsException, but that's trivial to your question.

apexlol
  • 130
  • 11
  • it's the answer I want. test(String...) need a variable length parameters, can I say like this: test(object) and object = flag? expression1: expression2, that's why both expressions must return the same type. – xiangflight Jan 12 '18 at 13:26