Рубрики
Без рубрики

С Java 8 на Java 15 за десять минут

В этом блоге вы найдете примеры потрясающих новых функций, добавленных с Java 7. Я продемонстрирую хотя бы один из них… С пометкой java, программирование, функционал.

В этом блоге вы найдете примеры потрясающих новых функций, добавленных с Java 7. Я продемонстрирую по крайней мере одно существенное улучшение для каждой версии Java, вплоть до Java 15, которая была выпущена осенью 2020 года. Java теперь полностью поддерживает лямбды , функциональное программирование , вывод типов через var , неизменяемые коллекции с простыми конструкторами и многострочные строки . Кроме того, появились новые захватывающие экспериментальные функции, такие как классы данных ( запись ) и запечатанные классы. Наконец, я расскажу о Java REPL , который предлагает высокую ценность для быстрых экспериментов.

Оглавление :

  • Функциональное программирование ( Java 8)
  • Потоки ( Java 8)
  • Необязательно ( Java 8)
  • JShell (Java 9)
  • Фабричный метод для неизменяемых коллекций (Java 9)
  • Вывод типа с помощью var (Java 10)
  • Запуск Одного Исходного Файла (Java 11)
  • Переключить выражение (Java 12: экспериментальный, полнофункциональный: Java 14)
  • Многострочные строки (Java 13: экспериментальный, полнофункциональный: Java 15)
  • Классы данных: запись (Java 14: экспериментальный)
  • instanceof без приведения (Java 14: экспериментальный)
  • Закрытые классы (Java 15: экспериментальный)
  • Бонус: Обновленные Условия лицензирования, начиная с Java 8

В Java 8 функциональное программирование и лямбды были добавлены в качестве языковых функций. Две основные парадигмы функционального программирования являются/| неизменяемыми значениями и повышение функций до уровня граждан первого класса. Данные проходят через конвейер шагов модификации, где каждый шаг принимает некоторый ввод и сопоставляет его с новым выводом. Функциональное программирование можно использовать с Streams и null-безопасными монадами ( Необязательно ) в Java, как показано ниже...

Для вашей обычной компьютерной программы вам часто приходится работать со списком значений и выполнять заданное преобразование для каждого значения . До Java 8 для этого преобразования приходилось использовать for loop , но теперь вы можете использовать Streams следующим образом:

Stream.of("hello", "great")
    .map(s -> s + " world")
    .forEach(System.out::println);
> hello world
> great world

Функция map принимает в качестве входных данных лямбда-выражение, которое будет применено ко всем элементам в потоке.

Потоки могут работать на Списки , Наборы и Карты (с помощью преобразования). Благодаря потокам вы можете избавиться практически от всех циклов в вашем коде! 👌

Другой распространенной проблемой в Java были исключения Нулевого указателя . Итак, Java представила Необязательно – монада, которая оборачивает ссылку, которая может быть или не быть нулевой. Применение обновлений к этому необязательному элементу может быть выполнено функциональным способом:

Optional.of(new Random().nextInt(10))
    .filter(i -> i % 2 == 0)
    .map(i -> "number is even: " + i)
    .ifPresent(System.out::println);
> number is even: 6

В приведенном выше фрагменте мы создаем случайное число, помещаем его в необязательный объект, а затем печатаем число только в том случае, если оно четное.

Наконец, у нас есть REPL для Java, и его имя Shell ! 😊 В двух словах, Shell позволяет экспериментировать с фрагментами Java без написания и компиляции полного Java-класса. Вместо этого вы можете выполнять по одной команде за раз , и вы сразу увидите результат. Вот простой пример:

$ /bin/jshell
jshell> System.out.println("hello world")
hello world

Люди, знакомые с интерпретируемыми языками, такими как JavaScript или Python, уже давно получили удовольствие от ОТВЕТА, но до сих пор эта функция отсутствовала в Java. Оболочка позволяет определять переменные , но также и более сложные объекты, такие как многострочные функции , классы и выполнение циклов . Кроме того, оболочка поддерживает автоматическое завершение, что очень удобно, если вы не знаете точных методов, предлагаемых данным классом Java.

Простая инициализация Списков долгое время отсутствовала в Java, но те времена прошли. 😅 Раньше вам приходилось делать что – то подобное:

jshell> List list = Arrays.asList(1, 2, 3, 4)
list ==> [1, 2, 3, 4]

Теперь это упрощено следующим образом:

jshell> List list = List.of(1, 2, 3, 4)
b ==> [1, 2, 3, 4]

Эта причудливая из(...) метод существует для списка , Набор и Карта . Все они создают неизменяемый объект всего в одной простой строке кода.

В Java 10 введено новое ключевое слово var , которое позволяет опускать тип переменной.

jshell> var x = new HashSet()
x ==> []

jshell> x.add("apple")
$1 ==> true

В приведенном выше фрагменте тип x может быть выведен как HashSet компилятором.

Эта функция помогает сократить количество шаблонного кода и улучшают удобочитаемость . Однако у этого есть некоторые ограничения: вы можете использовать var только внутри тел методов, и компилятор определит тип во время компиляции, так что все по-прежнему статически типизировано.

Ранее, когда вы писали простую Java-программу, состоящую из одного файла, вам нужно было сначала скомпилировать файл с помощью javac а затем запустите его с помощью java . В Java 11 вы можете выполнить оба шага с помощью одной команды:

Main.java :

public class Main {
  public static void main(String[] args) {
    System.out.println("hello world");
  }
}
$ java ./Main.java
hello world

Для простых начальных программ или экспериментов, состоящих всего из одного класса Java, эта функция для запуска отдельных исходных файлов облегчит вашу жизнь.

Java 12 принесла нам Выражения переключения . Вот краткая демонстрация того, как это выражение отличается от старого оператора switch.

Оператор old switch определяет поток программы:

jshell> var i = 3
jshell> String s;
jshell> switch(i) {
   ...>     case 1: s = "one"; break;
   ...>     case 2: s = "two"; break;
   ...>     case 3: s = "three"; break;
   ...>     default: s = "unknown number";
   ...> }
jshell> s
s ==> "three"

Напротив, выражение new switch возвращает значение:

jshell> var i = 3;
jshell> var x = switch(i) {
   ...>     case 1 -> "one";
   ...>     case 2 -> "two";
   ...>     case 3 -> "three";
   ...>     default -> "unknown number";
   ...> };
x ==> "three"

Подводя итог, старый оператор switch предназначен для потока программы, а новое выражение switch преобразуется в значение.

Обратите внимание, что этот новый оператор switch является своего рода функцией mapping : есть один вход (в приведенном выше случае i ), и есть один вывод (здесь x ). На самом деле это функция сопоставления с образцом , которая помогает сделать Java более совместимой с принципами функционального программирования . Аналогичный оператор switch уже некоторое время доступен в Scala.

Несколько вещей, на которые следует обратить внимание:

  • Вместо двойных точек мы используем стрелки ->
  • Нет необходимости в break
  • Случай по умолчанию может быть опущен, когда рассматриваются все возможные случаи
  • Чтобы включить эту функцию в Java 12, используйте --enable-preview --source 12

Вам когда-нибудь приходилось определять длинную многострочную строку , такую как JSON или XML? До сих пор вы, вероятно, помещали бы все в одну строку и использовали символы новой строки , До сих пор вы, вероятно, помещали бы все в одну строку и использовали символы новой строки А вот и Java 13 с многострочными строками ! 💪

Примерный случай:

public class Main
{ 
  public static void main(String [] args)
  {
    var s = """
        {
            "recipe": "watermelon smoothie",
            "duration": "10 mins",
            "items": ["watermelon", "lemon", "parsley"]
        }""";
    System.out.println(s);
  }
}

Теперь мы запускаем основной метод с помощью запуска одного файла:

java --enable-preview --source 13 Main.java

{
    "recipe": "watermelon smoothie",
    "duration": "10 mins",
    "items": ["watermelon", "lemon", "parsley"]
}

Результирующая строка занимает несколько строк, кавычки "" остаются нетронутыми, и даже табуляции \t сохраняются!

Из всех новых функций в этой статье это, вероятно, то, что меня больше всего волнует: наконец-то в Java есть классы данных ! Эти классы объявляются с помощью ключевого слова record и имеют автоматические средства получения, конструктор, метод equals() и т.д. Короче говоря, вы можете избавиться от огромного куска шаблонного кода! 🙌 🎉

jshell> record Employee (String name, int age, String department) {}
|  created record Employee

jshell> var x = new Employee("Anne", 25, "Legal");
x ==> Employee[name=Anne, age=25, department=Legal]

jshell> x.name()
$2 ==> "Anne"

Scala имеет аналогичную функцию с case classes , а Kotlin – с data classes . В Java многие разработчики использовали Ломбок до сих пор, который предлагал в значительной степени те функции, которые теперь вдохновили records для Java 14. Более подробную информацию можно найти в этой статье Baeldung .

Предыдущие версии Java уже содержали ключевое слово instanceof :

Object obj = new String("hello");
if (obj instanceof String) {
  System.out.println("String length: " + ((String)obj).length());
}

Неудачная часть: Сначала мы проверяем, что s имеет тип |/Строка , затем мы приводим его снова, чтобы получить его длину.

Теперь с Java 14 компилятор достаточно умен, чтобы автоматически определять тип после проверки instanceof :

Object obj = new String("hello");
if (obj instanceof String mystr) {
  System.out.println("String length: " + mystr.length());
}

С ключевым словом sealed , вы можете ограничить какие классы могут расширять данный класс или интерфейс. Вот пример:

public sealed interface Fruit permits Apple, Pear {
    String getName();
}

public final class Apple implements Fruit {
    public String getName() { return "Apple"; }
}

public final class Pear implements Fruit {
    public String getName() { return "Pear"; }
}

Так как же это нам поможет? Что ж, теперь вы знаете, сколько Фруктов есть. На самом деле это важный шаг в направлении полностью поддерживаемого сопоставления с образцом , где вы можете обрабатывать классы как перечисления. Это запечатано функция прекрасно сочетается с новым выражением switch , описанным ранее.

Последняя тема для этой статьи: лицензирование . Большинство из вас слышали это Oracle прекратила обновления для Java 8 (для бесплатной коммерческой версии). Итак, вот ваши варианты:

  • Используйте более новую версию Oracle JDK (Oracle предлагает бесплатные обновления для системы безопасности только в течение 6 месяцев после каждого выпуска)
  • Используйте и старую версию JDK на свой страх и риск
  • Используйте старый OpenJDK Версии Java, они по-прежнему получают обновления для системы безопасности от сообщества с открытым исходным кодом или стороннего поставщика
  • Заплатить Oracle за первоклассную поддержку (например, Java 8: поддержка до 2030 года)

Ниже вы можете увидеть ориентировочную продолжительность поддержки Oracle для каждого JDK:

Новая модель лицензирования Oracle зависит от нового цикла выпуска : Oracle будет выпускать новую версию Java каждые 6 месяцев. Этот новый цикл выпуска помогает Oracle быстрее улучшать Java, быстрее получать обратную связь с помощью экспериментальных функций и догонять более современные языки, такие как Scala , Kotlin и Python .

Если вас интересуют более подробные сведения о лицензировании, ознакомьтесь с этой статьей Medium .

Java прошла долгий путь за последние 6 лет, с тех пор на самом деле было выпущено 8 новых версий Java! 🚀 Все эти потрясающие новые функции помогают сделать Java конкурентоспособным вариантом по сравнению с другими конкурентами на основе JVM (Scala и Kotlin).

Если вы ищете еще более подробную информацию о новых функциях Java, начиная с Java 8, я могу порекомендовать эту статью DEV Эндрю , а также эту статью Дэвида Чаквари .

Я получил огромное удовольствие, написав эту статью 🔥 Спасибо за чтение 😊 Какая ваша любимая функция в недавнем выпуске java? Я был бы рад получить от вас обратную связь! Ваше здоровье!

Оригинал: “https://dev.to/pmgysel/from-java-8-to-java-15-in-ten-minutes-22f7”