Switch Expression

Switch Expression to usprawniona wersja instrukcji sterującej switch pozwalająca na przypisanie "wyniku switcha" od razu do zmiennej. Została wprowadzona w JDK 14.

Przykład Switch Expression

Od Javy 12 możliwości switcha zostały poszerzone. Do tej pory w blokach case można było wykonać obliczenia, czy wywołać metodę. Aktualnie poszczególne bloki case mogą zwrócić wynik, który następnie można przypisać np. do zmiennej. Może to wyglądać np. tak:

String season = "Winter";
String translation = switch (season) {
    case "Spring":
        yield "wiosna";
    case "Summer":
        yield "lato";
    case "Autumn":
        yield "jesień";
    case "Winter":
        yield "zima";
    default:
        yield "nieznany";
};

Jak można zauważyć do zwracania wartości służy polecenie yield, które jest trochę podobne do return. Return nie mógł być tutaj użyty, bo służy do zwracania z metody, a w tym przypadku chcemy zwracać ze switcha.

Kurs Java

Operator strzałki (->)

Istnieje także możliwość wykorzystania alternatywnego zapisu z operatorem strzałki, podobnym do tego, który wykorzystywany jest w wyrażeniach lambda. Powyższy przykład można przerobić na taki:

String season = "Winter";
String translation = switch (season) {
    case "Spring" -> "wiosna";
    case "Summer" -> "lato";
    case "Autumn" -> "jesień";
    case "Winter" -> "zima";
    default -> "nieznany";
};

Tych dwóch typów zapisów tzn. wykorzystujących słowo yield i operator strzałki nie można ze sobą mieszać, tzn. nie można jednego bloku case zapisywać w jeden, a innego w inny sposób:

String translation = switch (season) {
	case "Spring" -> "wiosna";
	case "Summer" -> "lato";
	case "Autumn" -> "jesień";
	case "Winter" -> "zima";
	default: yield "nieznany"; // błąd kompilacji
};

Kilka przypadków naraz

W jednym bloku case możesz obsłużyć kilka przypadków naraz. Działa to zarówno dla podejścia z yield:

String temperature = switch (season) {
	case "Spring", "Summer": yield "ciepło";
	case "Autumn", "Winter": yield "zimno";
	default: yield "nieznany";
};

Jak i zapisu strzałkowego:

String season = "Winter";
String temperature = switch (season) {
    case "Spring", "Summer" -> "ciepło";
    case "Autumn", "Winter" -> "zimno";
    default -> "nieznany";
};

Dalszy rozwój switcha

Można powiedzieć, że Swich Expression to pierwszy krok w rozwoju switcha. Kolejnym są prace nad Pattern Matching for switch, którego ostateczną wersję zobaczymy nie prędzej niż przed JDK 20.

Zanim wprowadzono Switch Expression

Zanim wprowadzono ten mechanizm, musieliśmy radzić sobie w ten sposób.

String season = "Winter";
switch (season) {
    case "Spring":
        System.out.println("Mamy aktualnie wiosnę");
        break;
    case "Summer":
        System.out.println("Mamy aktualnie lato");
        break;
    case "Autumn":
        System.out.println("Mamy aktualnie jesień");
        break;
    case "Winter":
        System.out.println("Mamy aktualnie zimę");
        break;
    default:
        System.out.println("Nie znam takiej pory roku");
}

Najczęściej jednak tworzono metody, które zwracały wynik poprzez umieszczanie return w każdym case.

static String getTranslation(String season) {
    switch (season) {
        case "Spring":
            return "wiosna";
        case "Summer":
            return "lato";
        case "Autumn":
            return "jesień";
        case "Winter":
            return "zima";
        default:
            return "nieznany";
    }
}

Ostatecznie wywołanie sprowadzało się do jednej linii:

String translation = getTranslation("Winter");

Historia wprowadzania do Języka

Początkowo mechanizm ten został wprowadzony w Javie 12 (JEP 325) jako tzw. preview feature, następnie w Javie 13 (JEP 354) przedstawiono drugi podgląd, a finalna funkcjonalność już bez zmian trafiła do Java 14 (JEP 361). Switch Expression są elementem projektu Amber, który przewiduje także wprowadzenie innych praktycznych zmian do Javy.

Co ciekawe, w Javie 12 używane było słowo kluczowe break do zwracania wartości:

String season = "Winter";
String translation = switch (season) {
    case "Spring":
        break "wiosna";
    case "Summer":
        break "lato";
    case "Autumn":
        break "jesień";
    case "Winter":
        break "zima";
    default:
        break "nieznany";
};

To samo słowo było od zawsze używane również do przerywania bloku case. Aby rozróżnić te dwie kwestie, od Javy 13 w przypadku zwracania wartości należy wykorzystać słowo yield.

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupe na Facebooku.