What Do Two Question Marks in a Row in a Ternary Clause Mean?

Viewed 580

I recently saw this ternary operation statement in a piece of Java code:

int getVal(Integer number, boolean required) {
    Integer val = number == null ? required ? 1 : 2 : 3;
    return val;
}

I've never seen a ternary statement with two question marks in a row like that (without any parentheses). If I play with the input values, I can get 1 to return if number == null and 3 to return otherwise, but it doesn't seem to matter what required is, 2 never gets returned.

What does this statement mean (i.e. how should I read it as a word statement of true/false conditions) and what would the inputs need to be for 2 to be returned?

5 Answers

This is why it’s always a good idea to explicitly add parentheses, so the intent is clear at a glance :

Integer val = number == null ? (required ? 1 : 2) : 3;

It is simply a nested ternary statement. Clearer by adding parentheses:

number == null ? (required ? 1 : 2) : 3;

what would the inputs need to be for 2 to be returned?

number = null and required = false

An expression of the form a ? b ? c : d : e uses the conditional operator twice. The only ambiguity is in which order.

It can not mean (a ? b) ? c : d : e because that would be a syntax error.

Therefore, it must mean a ? (b ? c : d) : e.

That is, it is equivalent to:

if (a) {
  if (b) {
    return c;
  } else {
    return d;
  }
} else {
  return e;
}

A more interesting case is

a ? b : c ? d : e

which could be read as

(a ? b : c) ? d : e 

or

a ? b : (c ? d : e)

To resolve this ambiguity, the Java language specification writes:

The conditional operator is syntactically right-associative (it groups right-to-left)

Thanks to @luk2302 and @racraman for your answers! Based on the parenthetical understanding you've laid out:

Integer val = number == null ? (required ? 1 : 2) : 3;

I just want to add that the way to "read" this as truth statements is:

If opt == null and required == true: 1
If opt == null and required == false: 2
If opt != null: 3   // value of required doesn't matter

I hope this helps others who may have trouble reading this statement.

(Note: I wasn't sure whether it was better to post this as an update to the question or not, but since it's technically "explanation," it seemed like answer was the best place for it. If you like my answer, please upvote @luk2302 and @racraman, since they are the ones who inspired this addition)

Should have added parenthesis, it would be clearer to understand

Integer val = number == null ? (required ? 1 : 2) : 3;

This is equivalent to

if (number == null)
{
    if (required == true)
    {
        return 1;
    }
    else 
    {
        return 2;
    }
}
else
{
    return 3;
}

Inputs need for 2 to return number = null and required = false

Related