Подтвердить что ты не робот

Можно ли использовать тройной/условный оператор Java (?:) для вызова методов вместо назначения значений?

В таких страницах, как http://en.wikipedia.org/wiki/?:, тройной/условный оператор ?: кажется для условных присвоений. Я попытался использовать его для вызова метода, например:

(condition) ? doThis() : doThat();

Оба метода возвращают void. Java говорит мне, что это не утверждение.

Итак, я предполагаю, что не могу вызвать вызов условного метода... или я могу?

4b9b3361

Ответ 1

Подумайте о тройных операторах, подобных методу в этом случае. Высказывание a ? b : c (для целей и целей, которые вы рассматриваете, см. Комментарий lasseespeholt) эквивалентно вызову метода псевдокода:

ternary(a, b, c)
    if a
        return b
    else
        return c

поэтому люди могут говорить такие вещи, как x = a ? b : c; это в основном как сказать x = ternary(a, b, c). Когда вы говорите (condition) ? doThis() : doThat(), вы действительно говорите:

if condition
    return doThis()
else
    return doThat()

Посмотрите, что произойдет, если мы попытаемся подставить методы для того, что они вернут.

 if condition
    return ???
 else
    return ???

Нет даже смысла рассматривать это. doThis() и doThat() ничего не возвращают, потому что void не является экземпляром типа, поэтому метод ternary тоже ничего не может вернуть, поэтому Java не знает, что делать с вашим выражением и жалуется.

Есть способы обойти это, но все они плохие практики (вы можете изменить свои методы, чтобы иметь возвращаемое значение, но ничего не делать с тем, что они возвращают, вы могли бы создавать новые методы, которые вызывают ваши методы, а затем возвращать null, и т.п.). В этом случае вам намного лучше использовать инструкцию if.

РЕДАКТИРОВАТЬ Кроме того, существует еще большая проблема. Даже если вы возвращали значения, Java не рассматривает a ? b : c инструкцию в любом смысле.

Ответ 2

Тернарный оператор - это просто синтаксический сахар.
Это упрощает чтение и запись кода, но это не добавляет реальной функциональности.
Его основное использование заключалось в том, чтобы сжать несколько строк кода в одну строку и было очень полезно при создании строк, которые немного отличаются друг от друга, основываясь на некоторых условиях.

например.

Collection<?> col = ...
System.out.println("There " + (col.size()==1 ? "is" : "are") + " "
     + col.size() + " " + (col.size()==1 ? "element" : "elements")
     + " in the collection");

вместо

Collection<?> col = ...
String message = "There ";
if(col.size()==1)
    message += "is";
else
    message += "are";
message += " "+col.size()
if(col.size()==1)
    message += " element";
else
    message += " elements";
message += " in the collection";
System.out.println(message);

Как вы можете видеть, это упрощает код.
(примечание: во втором примере лучше использовать StringBuilder вместо конкатенации строк)

Но так как (condition) ? doThis() : doThat(); (без возвращаемых значений) имеет то же значение, что и if(condition) doThis(); else doThat();, было бы два способа написания одного и того же, без добавления функциональности. Это только усложнит ситуацию:

  • для программистов: код не является однородным.
  • для реализации тернарного оператора: теперь он должен также поддержка void методов

Итак, Нет, тройная операция не может использоваться для вызова условного метода. Вместо этого используйте if-else:

if(condition)
    doThis();
else
    doThat(); 

Ответ 3

Тернарный (условный) оператор возвращает значение. Если ваши методы этого не делают, они не могут использоваться как части оператора (где он принимает значение).

Чтобы лучше понять это, подумайте об одном простом двоичном операторе: +. Он работает следующим образом:

<eval1> + <eval2>  -->  <value>

Он нуждается в 2 оцениваемых частях и возвращает другое. Если вы набрали

doThis() + doThat();

или даже

gimmeAValue = doThis() + doThat();

он потерпит неудачу, поскольку ни doThis(), ни doThat() не оценят что-либо (они "возвращают" void). Конечно, оба <eval1> и <eval2> должны иметь некоторый "совместимый" тип, чтобы оператор + мог обрабатывать их и возвращать значение некоторого типа.

Теперь посмотрим на тернарный оператор:

<evalBoolean> ? <eval1> : <eval2>  -->  <value>

Он принимает 3 оцениваемые части и возвращает значение.

Первая оценочная часть должна быть понятной (castable) компилятором как логическая. Он будет использоваться для определения того, какая из двух других подлежащих анализу частей должна быть возвращена.

Остальные две анализируемые части должны быть... хорошо... аналитическими. Что-то. Какой-то тип.

Другими словами: тернарный условный оператор предназначен для возврата чего-то, а не как разветвления кода. Используется следующим образом:

gimmeAValue = testMe() ? returnThis() : returnThat();