Что означает новое ключевое слово «yield» в Java 13? - PullRequest
6 голосов
/ 22 сентября 2019

В Java 13 введено ключевое слово yield для выражений switch.

Как его использовать и в чем отличие от значения по умолчанию return или break?

Ответы [ 3 ]

5 голосов
/ 22 сентября 2019

Q & A

Как я могу его использовать?

  1. С метками со стрелками, когда необходим полный блок:

    int value = switch (greeting) {
        case "hi" -> {
            System.out.println("I am not just yielding!");
            yield 1;
        }
        case "hello" -> {
            System.out.println("Me too.");
            yield 2;
        }
        default -> {
            System.out.println("OK");
            yield -1;
        }
    };
    
  2. Для традиционных блоков:

    int value = switch (greeting) {
        case "hi":
            System.out.println("I am not just yielding!");
            yield 1;
        case "hello":
            System.out.println("Me too.");
            yield 2;
        default:
            System.out.println("OK");
            yield -1;
    };
    

В чем разница с возвратом по умолчанию?

A *Оператор 1023 * возвращает управление вызывающему методу ( §8.4 , §15.12 ) или конструктору ( §8.8, §15.9 ), в то время как оператор yield передает управление с помощью , в результате чего включающее выражение switch создает указанное значение.

В чем разница со значением разрыва?

Оператор break со значением отбрасывается в пользу оператора yield.

Спецификация

Существует Спецификация для JEP 354 , прикрепленной к JSL 13 , которая суммирует все, что нам нужно знать о новом switch.Обратите внимание, что он не был объединен со спецификацией языка, потому что он все еще является функцией предварительного просмотра и, таким образом, еще не является постоянной частью языка.

A yield операторпередает управление, заставляя вмещающее выражение switch генерировать указанное значение.

YieldStatement:
    yield Expression;

A yield оператор пытается передать управление в самое внутреннее выражение переключения переключателя;это выражение, которое называется целевым значением доходности , затем сразу же нормально завершается, и значение Expression становится значением выражения switch.

  • Это ошибка времени компиляции, если у оператора yield нет цели выхода.

  • Это ошибка времени компиляции, если цель yield содержит какой-либо метод, конструктор, инициализаторили лямбда-выражение, которое содержит оператор yield.

  • Ошибка времени компиляции, если Expression оператора yield void (15.1).

Выполнение оператора yield сначала оценивает Expression.Если по какой-либо причине оценка Expression завершается преждевременно, то по этой причине оператор yield завершается преждевременно.Если оценка Expression завершается нормально, производя значение V, то оператор yield завершается внезапно, причиной чего является доходность со значением V.

5 голосов
/ 22 сентября 2019

Как часть JEP 354 (Java 13), вы можете yield значение переключателя (опционально назначить его переменной)

выражение yield для получения значения, которое становитсязначение выражения включающего переключателя.

int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        int k = day.toString().length();
        int result = f(k);
        yield result;
    }
};

Я думаю, что вы путаетесь с JEP 325 на Java 12, которые используют break для возврата значения:

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

int j = switch (day) {
     case MONDAY  -> 0;
     case TUESDAY -> 1;
     default      -> {
         int k = day.toString().length();
         int result = f(k);
         break result;

Кроме того, вы даже можете использовать лямбда-синтаксис

boolean result = switch (ternaryBool) {
    case TRUE -> true;
    case FALSE -> false;
    case FILE_NOT_FOUND -> throw new UncheckedIOException(
        "This is ridiculous!",
        new FileNotFoundException());
    // as we'll see in "Exhaustiveness", `default` is not necessary
    default -> throw new IllegalArgumentException("Seriously?! ?");
};

При использовании выражений переключателей весь блок переключателей «получает значение», которое затем может быть назначено;вы можете использовать лямбда-стиль синтаксиса

Хотя Java 12 представляет и уточняет выражения переключения 13, они делают это в качестве функции языка предварительного просмотра.Это означает, что (a) он все еще может измениться в течение следующих нескольких выпусков (как это было между 12 и 13) и (b) его необходимо разблокировать во время компиляции и во время выполнения с помощью новой опции командной строки --enable-предварительный просмотр.Тогда имейте в виду, что это не финал для переключения - это всего лишь шаг на пути к полному сопоставлению с образцом.

0 голосов
/ 22 сентября 2019

yield отмечает значение, которое будет возвращено из ветви переключателя.Он завершает выражение переключателя, вам не нужно иметь разрыв после него.

From doc

Два оператора break (с или безlabel) и yield, облегчают простое устранение неоднозначности между операторами switch и выражениями switch: оператор switch, но не выражение switch, может быть целью оператора break;и выражение switch, но не оператор switch, может быть целью оператора yield.

Он также обеспечивает, NullPointerException Safety,

String message = switch (errorCode) {
    case 404:
        yield "Not found!";
    case 500:
        yield "Internal server error!";
    // No default
};

Это приведет к,

выражение переключателя не охватывает все возможные входные значения

...