2015-01-29 3 views
2

Я бегу следующий фрагмент кодаПриоритет равенства и условных операторов в Java

System.out.println(T1() ? F1() : T2() == T3() ? F2() : T4()); 
public static boolean T1() { System.out.println("true1"); return true; } 
public static boolean T2() { System.out.println("true2"); return true; } 
public static boolean T3() { System.out.println("true3"); return true; } 
public static boolean T4() { System.out.println("true4"); return true; } 
public static boolean F1() { System.out.println("false1"); return false; } 
public static boolean F2() { System.out.println("false2"); return false; } 

Я получаю выход

true1 
false1 
false 

Первый троичный оператор был оценен перед оценивая оператор равенства, но в соответствии с oracle documentation оператор равенства имеет больший приоритет, чем тройной, поэтому оператор равенства должен быть оценен перед тройным.

В чем причина такого поведения кода?

+0

Мне кажется, что код был оценен так, как будто это был 'T1()? F1(): (T2() == T3()? F2(): T4()) ' – Dragondraikk

ответ

1

Вы, кажется, неправильно понимаете, что означает приоритет. Тот факт, что == имеет более высокий приоритет, чем тернарный оператор, не означает, что в выражении сначала вычисляются все подвыражения. Приоритет - это единственное средство для исключения скобок в определенных случаях.

Например, выражение

a == b ? c : d 

может быть эквивалентно либо (a==b) ? c : d или a == (b ? c : d). Тот факт, что == имеет более высокий приоритет, означает, что он фактически эквивалентен первому.

В выражении

a ? b : c == d 

нет никакой двусмысленности, она всегда эквивалентна a ? b : (c == d). Поскольку тернарный оператор оценивается лениво, если a имеет место, c == d никогда не оценивается.

+0

как и сказал, мы можем в некоторых случаях опустить скобки, так почему же здесь не такая же ситуация? '(a? B: c) == (d? F: g)' или '(a? B: (c == d? F: g))'. Почему более высокий приоритет '==' здесь не работает? – user1448906

+1

@ user1448906 Ну, так как == имеет более высокий приоритет, 'a? b: c == d? f: g' эквивалентно 'a? b: (c == d)? f: g', потому что тройственный оператор является право-ассоциативным, что, в свою очередь, эквивалентно 'a? b: ((c == d)? f: g) '. – Hoopje

7

JLS 15.25

Условный оператор синтаксически правоассоциативной (она группирует справа-налево). Таким образом, a? B: c? D: e? F: g означает то же самое, что и? B: (c? D: (e? F: g)).

А в вашем случае:

T1() ? F1() : (T2() == T3() ? F2() : T4()) 
    a  b   c   d  e 

T1() оценивается верно, возвращает истину, так что только F1() оценивается в следующем.

0

T2() == T3() не оценивается. Ваш код равен:

if(T1()) { 
    System.out.println(F1()); 
} 
else { 
    if(T2() == T3()) { 
    System.out.println(F2()); 
    } 
    else { 
    System.out.println(T4()); 
    } 
} 

Здесь вы ясно видите, почему он никогда не оценивали - потому T1() верно и else блок никогда не вошел.