Как стать автором
Обновить

Комментарии 15

Это прекрасно. Осталось только прод мигрировать с 8 версии

Upd: вроде можно же писать код для версии языка X и компилировать в версию языка Y, где X > Y?

Да, 8ка наше все. Думаю что очень много проектов еще на ней.

Кстати, в свое время мигрировали с 8 на 11 без особых проблем)

Можно взять для этого Jabel от bsideup.
Для pattern matching такой вариант не подойдёт так как нужна поддержка от стандартной библиотеки (см. SwitchBootstraps), но для чистого синтаксического сахара а-ля многострочные строковые литералы — вполне.

Определенно "годное" расширение возможностей Java. Вопрос только: насколько все это приживется, и как скоро перейдут на использование Java 17, после многолетнего использование Java8?

Ну а так, 17 версия Java внесла немало полезных возможностей и неплохую оптимизацию.

Preview и LTS немного противоречат друг другу.

Ну через два года будет новый LTS, думаю к нему вполне успеют довести ее до конца, а может ещё и дистракчеринг добавят.

Java 17: Pattern Matching for switch

Лично у меня язык не поднимается назвать это сопоставлением с образцом, так, немного адекватный switch и все. Ведь тут чего не хватает? Конструкции сопоставления с образцом есть суть выражения(на уровне семантики языка), а switch в Java никак к выражениям не относится. Вот и получилось опять невесть что, как у последователей карго-культа.

Хм, как то я и не заметил что все таки, в отличие от C#(<8.0) в Java это скорее сопоставление с образцом:

Java:

static String formatterPatternSwitch(Object o) {
return switch (o) {
case Integer i -> //....;
default -> o.toString();
};
}

C#:
switch (о) {
case Integer i:
.....;
break;
default:
......;
break;
}

Хотя вроде в C# 8.0 это все поправят и введут выражения. Интересно.

Switch expressions добавили ещё раньше, в рамках JEP 361.
И даже в рамках этой короткой статьи они встречаются:


static String formatterPatternSwitch(Object o) {
    return switch (o) {

Вот и получилось опять невесть что, как у последователей карго-культа.

Дружно бьём в бубен.

case (Integer i && i.intValue() > 3) && (i.intValue() < 7) -> { ...} 

case (Integer i && i.intValue() > 3) && (i.intValue() < 7) -> { ...}

Это точно? Или должно быть

case Integer i && (i.intValue() > 3 && i.intValue() < 7) -> { ...} 

?

Все верно, можете посмотреть JEP: 406 секцию Guarded and parenthesized patterns

JEP: 406 секцию Guarded and parenthesized patterns

GuardedPattern: PrimaryPattern && ConditionalAndExpression

В данном случае

PrimaryPattern = Integer i

ConditionalAndExpression = (i.intValue() > 3 && i.intValue() < 7)

Значит получаем так, как я написал:

case Integer i && (i.intValue() > 3 && i.intValue() < 7) -> { ...} 

We also change the grammar for instanceof expressions to:

InstanceofExpression:
  RelationalExpression instanceof ReferenceType
  RelationalExpression instanceof PrimaryPattern

This change, and the non-terminal ConditionalAndExpression in the grammar rule for a guarded pattern, ensure that, for example, the expression e instanceof String s && s.length() > 1 continues to unambiguously parse as the expression (e instanceof String s) && (s.length() > 1). If the trailing && is intended to be part of a guarded pattern then the entire pattern should be parenthesized, e.g., e instanceof (String s && s.length() > 1).


i.intValue() > 3 в данном примере является частью guarded паттерна (Integer i && i.intValue() > 3)

На самом деле, что в лоб, что по лбу:

public class GuardedSwitch {
    public static void main( String[] args ) {
        switchMethod( null );
        switchMethod( 1 );
        switchMethod( 4 );
        switchMethod( 7 );
        switchMethod( 10 );
        switchMethod( "Hello, world!" );
    }

    private static void switchMethod( Object a ) {
        System.out.println( switch( a ) {
            case null -> "NULL";
            case Integer i && ( i > 3 && i < 7) -> "(3 .. 7)";
            case ( Integer i && i >= 7) && ( i < 9 ) -> "[7 .. 9)";
            case Integer i && i >= 0 && i <= 3 -> "[0 .. 3]";
            case Integer i -> "Another Integer = " + i;
            default -> "Another object type: " + a.getClass().getTypeName() + " = " + a;
        } );
    }
}

Вывод:

NULL
[0 .. 3]
(3 .. 7)
[7 .. 9)
Another Integer = 10
Another object type: java.lang.String = Hello, world!
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.