Должны ли оба правых выражения троичного оператора быть совместимых типов? - PullRequest
0 голосов
/ 03 июня 2018

Книга «Мои практические тесты» содержит следующий вопрос о троичном операторе:

// 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); компилируется и запускается без проблем.

Ответы [ 3 ]

0 голосов
/ 03 июня 2018

это действительно причина?Мне кажется, что этот пример не компилируется, потому что 10 не является строкой, а метод String - это то, что должен возвращать метод

И ваши рассуждения, и ответ автора верны.
Я думаю, что правильным ответом на ваш вопрос является их объединение.

1) Тернарный оператор недействителен

, потому что

2) в текущем контексте тип, который вы ему присвоили: int не может быть назначен String.

Вы можете проверить это с помощью сообщений об ошибках, генерируемых компилятором.

Здесь вы должны учитывать, что:

return(distance < 1000 ? "train" : 10);

как две вещи для оценки компилятором:

1) distance < 1000 ? "train" : 10 // выдает результат

2) returns (the produced result); // возвращает результат, который должен быть назначен на строку в соответствии с типом возврата метода

На самом деле, ошибка компиляции:

Транспортировка.Java: 3: ошибка: несовместимые типы: неверный тип в возвращении условного выражения (расстояние <1000? "train": 10); <br>int не может быть преобразовано в строку

ссылается на обе ошибки: ошибка условного выражения и ее причина: ошибка несовместимости между int и String .

Таким образом, ошибка компиляции, касающаяся только несовместимости между int и String в return, будет иметь место, только если троичный код действителен во время компиляции.

Напишите правильное троичное выражение, и вы увидите, что компилятор выдаст только ошибку об операторе return:

public static String travel(int distance) {
    return(distance < 1000 ? 15 : 10);
}

ошибка: несовместимые типы: int не может бытьпреобразуется в строку

0 голосов
/ 03 июня 2018

Вы правы, объяснение сбивает с толку, поскольку для выражений правой руки могут использоваться разные совместимые типы.

Вы можете найти таблицу результирующего типа условного выражения в соответствии с типами второго и третьего операнда здесь .

Может быть приведено несколько типов счисловые типы, как объяснено в этом вопросе .

0 голосов
/ 03 июня 2018

Ваш метод объявляет, что тип возвращаемого значения 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? "Train": 10);компилируется и запускается без проблем. </p>

Это связано с тем, что компилятор определяет общий тип для 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) аналогично последнему примеру выше, где ожидаемый тип совместим с обоими выражениями.

...