Синтаксис case Success(var value) в java

Встретил такую конструкцию в коде

Integer a = switch (result) {
    case Success(var value) -> value;
    case Failure(Throwable e) -> Assertions.fail();
};

Не понял конкретно, зачем в конструктор пихать var value

case Success(var value)

Попробовал погуглить про switch, но что-то ничего похожего не вижу.

Подскажите, пожалуйста, как эта конструкция называется, или статейку киньте про нее.


Ответы (1 шт):

Автор решения: Nowhere Man

В данном случае case Success(var value) -- не конструктор, а относительно новая фича, добавленная в Java 21 (см. JEP 441: Pattern Matching for switch, JEP 440: Record Patterns) -- сопоставление шаблонов в switch-выражениях (pattern matching in switch expressions) для кортежей (record).

В частности, в данном случае используется шаблон для проверки обобщенных кортежей (generic record), для которых применяется извлечение типа (type inference) при помощи var.

Официальная документация: Pattern Matching for switch Expressions and Statements :: Inference of Type Arguments in Record Patterns

// обобщённый кортеж
record MyPair<T, U>(T x, U y) { }

static void recordInference(MyPair<String, Integer> p){
    switch (p) {
        case MyPair(var s, var i) -> 
            System.out.println(s + ", #" + i);
    }
}

Здесь компилятор извлечёт тип для MyPair(var s, var i) как MyPair<String, Integer>(String s, Integer i)

Также извлечение типа при сопоставлении шаблонов для кортежей может использоваться и с instanceof:

record Point(double x, double y) {}

static void printAngleFromXAxis(Object obj) {
    if (obj instanceof Point(var x, var y)) {
        System.out.println(Math.toDegrees(Math.atan2(y, x)));
    }
}

Здесь компилятор "поймёт", что x, y будут иметь тип double.

Аналогично для обобщённого кортежа Box(var s) компилятор определит тип как Box<String>(String s)

record Box<T>(T t) { }

static void printBoxContentsAgain(Box<String> bo) {
    if (bo instanceof Box(var s)) {
        System.out.println("Box contains: " + s);
    }
}

Так что в свете вышесказанного в вашем коде где-то определены кортежи вида record Success<T>(T value) {}, record Failure(Throwable e) {}, и ожидается, что переменная result может принимать один из двух указанных типов, в частности типизированный Success<Integer>(Integer value) в случае успеха.

→ Ссылка