¿Qué significa la nueva palabra clave “rendimiento” en Java 13?

6 minutos de lectura

avatar de usuario de zerocewl
cero cewl

Java 13 introdujo el yield palabra clave para switch expresiones

¿Cómo puedo usarlo y cuál es la diferencia con un valor predeterminado? return o break ¿valor?

  • Solo se usa para especificar un valor de retorno desde dentro de un switch declaración. es diferente a un return como lo rendimientos de una declaración en lugar de devoluciones de un método.

    – Boris la araña

    22 de septiembre de 2019 a las 12:25


  • @BoristheSpider Java 12 utilizado break <value>la return <value> solo se consideró iirc, pero nunca formó parte de una versión lanzada.

    – Mark Rotteveel

    22 de septiembre de 2019 a las 12:28

  • Cabe resaltar que yield no es una palabra clave. Thread tiene un yield() método que está ahí para quedarse, y puede nombrar cualquiera de sus variables, campos, métodos o etiquetas yield siempre que su espacio de nombres lo permita.

    – Ahmad Shahwan

    18 oct a las 19:36

Avatar de usuario de Andrew Tobilko
andres tobilko

Preguntas y respuestas

¿Como puedo usar lo?

  1. Con etiquetas de flecha cuando se necesita un bloque completo:

    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. Con bloques tradicionales:

    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;
    };
    

¿Cuál es la diferencia con una devolución predeterminada?

A return instrucción devuelve el control a el invocador de un método (§8.4, §15.12) o constructor (§8.8, §15.9) mientras que un yield declaración transfiere el control por provocando un encierro switch expresión para producir un valor especificado.

¿Cuál es la diferencia con un valor de ruptura?

los break con declaración de valor se abandona en favor de una yield declaración.

Especificación

Hay Especificación para JEP 354 adjunto a el JLS 13 que resume todo lo que necesitamos saber sobre el nuevo switch. Tenga en cuenta que no se fusionó con la especificación del idioma porque todavía es una función de vista previa y, por lo tanto, aún no es una parte permanente del idioma.

A yield instrucción transfiere el control provocando un cierre switch expresión para producir un valor especificado.

YieldStatement:
    yield Expression;

A yield la instrucción intenta transferir el control a la expresión de cambio más interna; esta expresión, que se llama el objetivo de rendimientoluego inmediatamente se completa normalmente y el valor de la Expression se convierte en el valor de la switch expresión.

  • Es un error en tiempo de compilación si un yield declaración no tiene objetivo de rendimiento.

  • Es un error en tiempo de compilación si el yield target contiene cualquier método, constructor, inicializador o expresión lambda que incluya la instrucción yield.

  • Es un error en tiempo de compilación si el Expression de un yield declaración es nula (15.1).

ejecución de un yield declaración primero evalúa el Expression. Si la evaluación de la Expression termina abruptamente por alguna razón, entonces el yield declaración se completa abruptamente por esa razón. Si la evaluación de la Expression se completa normalmente, produciendo un valor Ventonces el yield declaración se completa abruptamente, la razón es un rendimiento con valor V.

avatar de usuario de user7294900
usuario7294900

Como parte de JEP 354 (Java 13), puede rendir valor en el interruptor (opcionalmente asignarlo a la variable)

declaración de rendimiento para generar un valor, que se convierte en el valor de la expresión de cambio adjunta.

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

Creo que tu confusión es con JPY 325 en Java 12 que usa break para devolver valor:

hemos ampliado la sentencia break para que tome un argumento, que se convierte en el valor de la expresión switch adjunta.

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

Además, incluso puedes usar sintaxis lambda

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?! 🤬");
};

Con las expresiones de cambio, todo el bloque de cambio “obtiene un valor” que luego se puede asignar; puede usar una sintaxis de estilo lambda

Si bien Java 12 presenta y 13 refina las expresiones de cambio, lo hacen como una función de lenguaje de vista previa. Eso significa que (a) aún puede cambiar en las próximas versiones (como sucedió entre la 12 y la 13) y (b) debe desbloquearse, en tiempo de compilación y tiempo de ejecución, con la nueva opción de línea de comando –habilitar- avance. Después tenga en cuenta que este no es el final del juego para el cambio, es solo un paso en el camino hacia la coincidencia completa de patrones.

  • ¿Alguien sabe por qué se cambió esto de JDK 12? La JEP no da mucha idea de por qué yield fue elegido sobre break.

    – Druckles

    22 de septiembre de 2019 a las 12:56


  • @Druckles parece una elección separarse descanso para romper el interruptor y rendir para el valor de retorno, consulte metebalci.com/blog/lo-nuevo-en-java-13/… también usando el descanso puede moverse a la etiqueta ver docs.oracle.com/javase/specs/jls/se13/preview/…

    – usuario7294900

    22 de septiembre de 2019 a las 13:06


  • @Druckles Se cambió porque, en nuestra investigación con los usuarios, las personas encontraron la sobrecarga de break confuso.

    – Brian Goetz

    22 de septiembre de 2019 a las 16:49

  • @BrianGoetz eso es confuso. Aunque, me gustó la analogía con las dos formas de return mencionado aquí

    – Andrew Tobilko

    22 sep 2019 a las 21:11


  • return@ en Kotlin es una solución mucho mejor que nueva palabra clave…

    – Andrew Sneck

    9 de mayo de 2021 a las 7:43

Avatar de usuario de Vikas
Vikas

yield marca el valor que se devolverá desde una rama de conmutación. Termina la expresión de cambio, no necesita tener un descanso después.

De doc

Las dos sentencias, break (con o sin etiqueta) y yield, facilitan la desambiguación entre sentencias switch y expresiones switch: una sentencia switch, pero no una expresión switch, puede ser el objetivo de una sentencia break; y una expresión de cambio, pero no una declaración de cambio, puede ser el objetivo de una declaración de rendimiento.

También proporciona, NullPointerException La seguridad,

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

Esto resultará en,

la expresión de cambio no cubre todos los valores de entrada posibles

avatar de usuario de ricky
Ricky

break replace with yield en Java 13. Esta es una de las funciones de vista previa definidas en Java 13. En Java 12, podemos usar break para devolver un valor de un interruptor. Pero en java 13 use el rendimiento para el valor de retorno de la expresión de cambio.

En Java 13 romper reemplazar por rendimiento,

String number = switch (number) {
    case 1:
        yield "one";
    case 2:
        yield "two";
    default:
        yield "Zero";
}

La sintaxis de flecha todavía es compatible con Java 13.

String number = switch (number) {
    case 1 -> "one";
    case 2 -> "two";
    default -> "Zero";
}

¿Ha sido útil esta solución?