1

I have a piece of code like follows

public class Test{
               public static void main(String[] args) {
                  System.out.println(true?false:true == true?false:true);
                                                -----------------------
               }
            }

The output is false. If you are using Eclipse you get a wavy (dashed here) line and warning like "Comparing identical expressions". Note the start of the wavy line.

I changed the code to the following

              public class Test{
               public static void main(String[] args) {
                  System.out.println((true?false:true) == (true?false:true));
                                     ---------------------------------------
               }
            }

The output is true. If you are using Eclipse you get a wavy (dashed here) line and warning like "Comparing identical expressions". Note the start of the wavy line now.

Why the difference?

3
  • I'm not sure what your question is. You are comparing two identical expressions, as the message says. What are you expecting to happen? Commented Jan 17, 2012 at 20:17
  • 2
    U don' need to short'n errythang. 's no twittah. Commented Jan 17, 2012 at 20:19
  • see the final outcome. it's diff in both case Commented Jan 17, 2012 at 20:21

4 Answers 4

3

Because ternary operator (?:) has lower priority than equality operator (==). This means that:

true?false:true == true?false:true

is actually interpreted as:

true?false:(true == true?false:true)

This, in turns, is evaluated to:

true?false:((true == true)?false:true)

cont.:

true?false:(true?false:true)

...and eventually:

true?false:(false)

and eventually:

true?false:false

And obviously this explains the output of the first code snippet. Eclipse correctly recognizes operator precedence and highlights possibly incorrect statement.

UPDATE: Thanks for all the comments. In fact I forgot about operator precedence on the left side. I checked the exact behaviour using the program below:

public static boolean a(char label, boolean result) {
    System.out.println(label);
    return result;
}

public static void main(String[] args) {
    System.out.println(
        a('a', true) ? a('b', false) : a('c', true) == a('d', true) ? a('e', false) : a('f', true)
    );
}

The results are consistent with @Milad Naseri suggestion.

Sign up to request clarification or add additional context in comments.

3 Comments

why (true == true?false:true) in step 1 gets reduced to (true == false). I think here u violated your priority which you talked in the first line. Just a thinking..
@Tomasz Nurkiewicz, Saurabh Kumar is right on that one; the third step doesn't have the part after the colon evaluate to (true == false), it simply evaluates to (false).
(true == true?false:true) in step three evaluates to (true==true)?false:true which becomes true?false:true which ultimately becomes false resulting in the value of the fourth step: true?false:false.
2

There is nothing unexpected here, the answer is operator precedence. In the first case it is:
true?false:(true == true?false:true)
While the in the second case your paretheses override the precedence rules.

Comments

1

In case your problem is the difference of outcomes, this is because of the order of precedence of the operators you use. Check here for details. According to that order of precedence:

true ? false : true == true ? false : true

is the same as this:

true ? false : ((true == true) ? false : true)

so it will always evaluate to false. You could put anything after the colon since it's never evaluated anyway (if I remember correctly and the ternary operator uses lazy evaluation); the reason for this is that

true ? A : B

always evaluates to A.


On the other hand,

(true ? false : true) == (true ? false : true)

will have both sides of the comparison operator == evaluate to false, so

false == false

which is a true statement.

So the difference here is the order in which the operators are evaluated, which is determined by the parentheses you use and, if there is ambiguity that isn't resolved by parentheses, by the order of precedence of the operators that are used.


In general, the ternary operator "? :" works like this

A ? B : C

If A is true, evaluate to B, else evaluate to C. A has to be a boolean expression, B and C can be whatever you want; you'll have to deal with type mismatches though if you want to assign the evaluated value to a variable and they are of different types.

Comments

1

That is because the conditional equality operator (==) takes precedence over the ternary conditional ?:. So, in a?b:x==y?z:t x==y?z:t is evaluated before a?b:x and y?z:t are.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.