Comments 15
Это прекрасно. Осталось только прод мигрировать с 8 версии
Upd: вроде можно же писать код для версии языка X и компилировать в версию языка Y, где X > Y?
Да, 8ка наше все. Думаю что очень много проектов еще на ней.
Кстати, в свое время мигрировали с 8 на 11 без особых проблем)
Можно, но это путь ко всевозможным NoClassDefFoundError, NoSuchFieldError, NoSuchMethodError и прочим LinkageError-ам.
Можно взять для этого Jabel от bsideup.
Для pattern matching такой вариант не подойдёт так как нужна поддержка от стандартной библиотеки (см. SwitchBootstraps), но для чистого синтаксического сахара а-ля многострочные строковые литералы — вполне.
Определенно "годное" расширение возможностей Java. Вопрос только: насколько все это приживется, и как скоро перейдут на использование Java 17, после многолетнего использование Java8?
Ну а так, 17 версия Java внесла немало полезных возможностей и неплохую оптимизацию.
Preview и LTS немного противоречат друг другу.
Java 17: Pattern Matching for switch
Лично у меня язык не поднимается назвать это сопоставлением с образцом, так, немного адекватный switch и все. Ведь тут чего не хватает? Конструкции сопоставления с образцом есть суть выражения(на уровне семантики языка), а switch в Java никак к выражениям не относится. Вот и получилось опять невесть что, как у последователей карго-культа.
Хм, как то я и не заметил что все таки, в отличие от C#(<8.0) в Java это скорее сопоставление с образцом:
Java:static String formatterPatternSwitch(Object o) {
C#:
return switch (o) {
case Integer i -> //....;
default -> o.toString();
};
}switch (о) {
case Integer i:
.....;
break;
default:
......;
break;
}
Хотя вроде в C# 8.0 это все поправят и введут выражения. Интересно.
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
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!
Java 17: Pattern Matching for switch