javaswitch-statementjava-12java-13

Return outside of enclosing switch expression


I'm using a switch expression¹ in Java 12 to convert a string to a HTTP method:

static Optional<RequestMethod> parseRequestMethod(String methodStr) {
    return Optional.ofNullable(
          switch (methodStr.strip().toUpperCase(Locale.ROOT)) {
              case "GET" -> RequestMethod.GET;
              case "PUT" -> RequestMethod.PUT;
              case "POST" -> RequestMethod.POST;
              case "HEAD" -> RequestMethod.HEAD;

              default -> {
                  log.warn("Unsupported request method: '{}'", methodStr);
                  return null;
              }
          });
}

I'd like to warn about the unsupported method in the default branch and return null (which is then wrapped in an Optional).

But the code above causes a compiler error:

Return outside of enclosing switch expression

How do I get this to compile?


For completeness, here's the definition of the RequestMethod enum:

enum RequestMethod {GET, PUT, POST, HEAD}

¹ switch expressions were introduced in Java 12 as a preview feature.


Solution

  • use yield in Java 13

    In Java 13, switch expressions use the new restricted identifier¹ yield to return a value from a block:

    return Optional.ofNullable(
            switch (methodStr.strip().toUpperCase(Locale.ROOT)) {
                case "GET" -> RequestMethod.GET;
                // ... rest omitted
    
                default -> {
                    log.warn("Unsupported request method: '{}'", methodStr);
                    // yield instead of return
                    yield null;
                }
            });
    

    use break in Java 12

    In Java 12, switch expressions use break to return a value from a block:

    return Optional.ofNullable(
            switch (methodStr.strip().toUpperCase(Locale.ROOT)) {
                case "GET" -> RequestMethod.GET;
                // ... rest omitted
    
                default -> {
                    log.warn("Unsupported request method: '{}'", methodStr);
                    // break instead of return
                    break null;
                }
            });
    

    ¹ yield is not a keyword, as helpfully pointed out by user skomisa.