Должны ли как правые выражения тернарного оператора быть совместимыми типами?
В моей книге "Тесты практики" содержится этот вопрос о тройном операторе:
// What is the output of the following application?
public class Transportation {
public static String travel(int distance) {
return(distance < 1000 ? "train" : 10);
}
public static void main(String[] args) {
travel(500);
}
}
Он не компилируется. Ниже приводится объяснение:
Тернарные операции требуют, чтобы оба правых выражения соответствовали типам данных. В этом примере первое правое выражение внешней тройной операции имеет тип String, а второе правое выражение имеет тип int. Поскольку эти типы данных несовместимы, код не компилируется, а вариант C - правильный ответ.
Это действительно причина? Мне кажется, что этот пример не компилируется, потому что 10 не является String, а String - тем, что должен вернуть метод. Я спрашиваю, потому что System.out.println(distance < 1000? "train": 10);
компилируется и работает без проблем.
Ответы
Ответ 1
Ваш метод объявляет, что тип возврата - String
. Любой оператор return
должен выдать выражение, совместимое с объявленным типом возвращаемого значения.
В этом случае, однако, тип возврата может быть int
, что объясняет, почему компилятор его отклоняет.
Это не относится к тернарному оператору, его можно воспроизвести с помощью эквивалентного блока if
/else
:
if(distance < 1000)
return "train"; //This part is valid
else
return 10; //This line will be rejected by the compiler
По той же причине последняя строка не скомпилируется. Это просто из-за базовой проверки типов.
System.out.println (расстояние <1000? "Поезд": 10); компилируется и работает без проблем.
Это связано с тем, что компилятор обнаруживает общий тип для String
и int
, который является Object
, и решает выбрать эту подпись:
java.io.PrintStream#println(Object x) // available in the target class
Это, однако, не применимо к типу возвращаемого метода.
Если вы изменили свой тип возврата на Object
, ваш код тоже скомпилировался. Но это, конечно, не то, что вы пытаетесь сделать.
Тернарные операции требуют, чтобы оба правых выражения соответствовали типам данных
→ Эта часть действительно действительна. вот способ интерпретировать его: каждое из двух выражений должно быть индивидуально совместимым:
String value = distance > 1000 ?
"train" //this must be compatible with String
:
10 //this too must be compatible with String (it isn't)
По сравнению:
Object value = distance > 1000 ?
"train" //this must be compatible with Object (it is)
:
10 //this too must be compatible with Object (it is)
Другими словами, вызов System.out.println(distance < 1000? "train": 10)
аналогичен предыдущему примеру выше, где ожидаемый тип совместим с обоими выражениями.
Ответ 2
это действительно причина? Мне кажется, что этот пример не компилируется, потому что 10 не является String, а String - тем, что метод должен возвращать
Правильны и ваши рассуждения, и ответ автора.
Я думаю, что правильный ответ на ваш вопрос - это их объединение.
1) недействителен оператор Ternary
так как
2) в текущем контексте - тип, которому вы его назначили: int
не может быть назначен для String
.
Вы можете проверить его с помощью сообщений об ошибках, отправленных компилятором.
Здесь вы должны учитывать, что:
return(distance < 1000 ? "train" : 10);
как две вещи для оценки компилятором:
1) distance < 1000? "train": 10
distance < 1000? "train": 10
//дает результат
2) returns (the produced result);
// возвращаем результат, который должен быть назначен String в соответствии с типом возвращаемого метода
Собственно, ошибка компиляции:
Transport.java:3: ошибка: несовместимые типы: плохой тип в условном выражении return (расстояние <1000? "Поезд": 10);
int не может быть преобразован в String
ссылается на обе ошибки: ошибка в условном выражении и его причина: ошибка несовместимости между int и String.
Таким образом, ошибка компиляции, которая ссылается только на несовместимость между int и String в return
будет возникать только в том случае, если тройка действительна во время компиляции.
Напишите действительное тернарное выражение, и вы увидите, что компилятор будет сигнализировать только об ошибке в отношении оператора return
:
public static String travel(int distance) {
return(distance < 1000 ? 15 : 10);
}
error: несовместимые типы: int не может быть преобразован в String
Ответ 3
Вы правы, объяснение сбивает с толку, поскольку для правильных выражений можно использовать различные совместимые типы.
Вы можете найти таблицу результирующего типа условного выражения в соответствии с типами второго и третьего операнда здесь.
Может быть какой-то тип литья с числовыми типами, как объясняется в этом вопросе.