Повторення — основа навчання. Хоча раніше ми вже говорили про switch у Java, сьогодні згадаємо основне і розберемо трохи нової інформації.

Java має два варіанти switch — це switch statement і switch expression. Switch expression офіційно був у Java у версії 14, маючи до цього 2 модифікації у 12 та 13 версіях.

Але почнемо спочатку: згадаємо, як виглядає старий світч до версії 12:

public String getProductTypeByName(String product) {
    String productType = "";

    switch (product) {
        case "Apple":
            productType = "Fruit";
            break;

        case "Peach":
            productType = "Fruit";
            break;

        case "Raspberry":
            productType = "Berry";
            break;

        case "Cherry":
            productType = "Berry";
            break;

        case "Tomato":
            productType = "Vegetables";
            break;

        default:
            productType = "other";
            break;
    }

    return productType;
}

switch statement — це набір конструкцій, які виконуватимуться один за одним, не даючи змогу повернути результат виконання. Головна проблема використання switch statement полягає в тому, що він дозволяє додавати нескінченну кількість case виразів, і цим часто зловживають програмісти.

У Java 12 його додали як experimental feature, і вже не як switch statement, a як switch expression — нову версію світчу, яка дає можливість зберігати результат виконання, використовувати функціональний підхід усередині та групувати значення в case виразах, у такий спосіб дозволяючи зробити його компактним.

Переписати метод getProductTypeByName() з використанням Java 12 можна так:

public String getProductTypeByName(String product) {
    return switch (product) {
        case "Apple", "Peach" -> "Fruit";
        case "Raspberry", "Cherry" -> "Berry";
        case "Tomato" -> "Vegetables";
        default -> "other";

    };
}

Тепер код виглядає охайніше. Використання arrow syntax із функціонального програмування дає можливість повертати значення без ключового слова break, і взагалі результат виконання switch тепер можна зберегти до змінної або повернути через return.

У випадках, коли потрібно не тільки повернути результат, але й мати кілька рядків коду, switch буде наступним:

public String getProductTypeByName(String product) {
    var result = switch (product) {
        case "Apple", "Peach" -> {
            System.out.println("This is fruit");
            break "Fruit";
        }
        case "Raspberry", "Cherry" -> {
            System.out.println("This is a Berry");
            break "Berry";
        }
        case "Tomato" -> {
            System.out.println("This is a Vegetables");
            break "Vegetables";
        }
        default -> {
            break "other";
        }

    };
     return result;
}

У Java 13 switch expression все ще знаходиться в статусі experimental feature, і щоб він був доступний для запуску, як і в Java 12, потрібно використовувати команду --enable-preview для компіляції та для запуску. Головне й по суті єдине “оновлення” switch в Java 13 – це ключове слово yield, яке замінило break.

public String getProductTypeByName(String product) {
    var result = switch (product) {
        case "Apple", "Peach" -> {
            System.out.println("This is fruit");
            yield "Fruit";
        }
        case "Raspberry", "Cherry" -> {
            System.out.println("This is a Berry");
            yield "Berry";
        }
        case "Tomato" -> {
            System.out.println("This is a Vegetables");
            yield "Vegetables";
        }
        default -> {
            System.out.println("Other");
            yield "other";
        }

    };
    return result;
}

Головною відмінністю yield від break є те, що break повертав управління з case – команди, коли yield повертає результат із цілого switch, граючи роль внутрішнього return-a.

У Java 14 змінився оператор instanceOf, і тепер його можна використовувати ось так:

if(o instanceof String s) {
s.toLowerCase();
}

Замість старого і не дуже гарного варіанту, де окрім перевірки на instanceOf потрібно ще обов'язково приводити змінну до певного типу.

if(s instanceof String) {
((String) s).toLowerCase();
}

Ці зміни є частиною проєкту Amber, мета якого – додати у Java підтримку pattern matching.

Завдяки зміні оператора instanceOf в 14 версії і розширення в 16, Pattern Matching все ж таки додали в 17 версії. Правда поки що лише як preview, і протестувати його можна за допомогою --enable-preview:

public String getObjectType(Object object) {
    return switch (object) {
        case Integer i -> "Integer";
        case Long l -> "Long";
        case String s -> "String";
        default -> object.toString();
    };
}

Взагалі з кожною новою версією в мові з'являється все більше і більше цікавих фішок для розробки, що робить Java ще крутішою.