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

Что нового в Java 15

Функции Java 15 – Запечатанные типы, записи, шаблоны, скрытые классы, текстовые блоки.

Автор оригинала: mkyong.

Java 15 стала общедоступной 15 сентября 2020 года, загрузите Java 15 здесь .

Функции Java 15.

  • 1. JEP 339: Алгоритм цифровой подписи Edwards-Curve (DSA)
  • 2. JEP 360: Закрытые классы (предварительный просмотр)
  • 3. JEP 371: Скрытые Классы
  • 4. JEP 372: Удалите движок JavaScript Nashorn
  • 5. JEP 373: Переопределите устаревший API DatagramSocket
  • 6. JEP 374: Отключить и запретить Смещенная блокировка
  • 7. JEP 375: Сопоставление с образцом, например (второй предварительный просмотр)
  • 8. JEP 377: ZGC: Масштабируемый Сборщик Мусора с Низкой задержкой
  • 9. JEP 378: Текстовые блоки
  • 10. JEP 379: Шенандоа: Сборщик мусора с низким временем паузы
  • 11. JEP 381: Удалите Solaris и SPARC Порты
  • 12. JEP 383: API доступа к внешней памяти (второй инкубатор)
  • 13. JEP 384: Записи (второй предварительный просмотр)
  • 14. JEP 385: Отмените активацию RMI для удаления

Функции разработчика Java 15.

Запечатанные типы (предварительный просмотр), записи (второй предварительный просмотр), сопоставление с образцом (второй предварительный просмотр), скрытые классы, текстовые блоки или многострочные (стандартные), API доступа к внешней памяти (второй инкубатор).

Примечание Что нового в последней версии Java 16 .

1. JEP 339: Алгоритм цифровой подписи Edwards-Curve (DSA)

Материал, связанный с криптографией, Java 15 реализует дополнительную схему цифровой подписи с использованием алгоритма цифровой подписи Edwards-Curve (EdDSA) , как описано в RFC 8032 . Схема подписи Dsa популярна благодаря своей повышенной безопасности и производительности (быстрее) по сравнению с другими схемами подписи, а также является одной из схем подписей, которые разрешены в TLS 1.3 .

Просмотрите алгоритмы подписи Java 15 |/.

Пример кода.

package com.mkyong.java15.jep339;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;

public class JEP339 {

    public static void main(String[] args)
        throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {

        KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
        KeyPair kp = kpg.generateKeyPair();

        byte[] msg = "abc".getBytes(StandardCharsets.UTF_8);

        Signature sig = Signature.getInstance("Ed25519");
        sig.initSign(kp.getPrivate());
        sig.update(msg);
        byte[] s = sig.sign();

        System.out.println(Base64.getEncoder().encodeToString(s));

    }
}

Дальнейшее чтение

2. JEP 360: Закрытые классы (предварительный просмотр)

В этом джипе появилось несколько новых ключевых слов, запечатанные , не запечатанные , разрешения для поддержки запечатанных классов и интерфейсов . Закрытые классы и интерфейсы ограничивают, кто может быть подтипом.

2.1 Приведенный ниже запечатанный интерфейс позволил реализовать его трем указанным подклассам.

public sealed interface Command
    permits LoginCommand, LogoutCommand, PluginCommand{
    //...
}

2.2 Для недопустимого класса он выдает ошибки во время компиляции:

public final class UnknownCommand implements Command {
  //...
}
class is not allowed to extend sealed class: Command

2.3 Запечатанный класс должен иметь подклассы и Каждый разрешенный подкласс должен выбрать модификатор (запечатанный, не запечатанный, окончательный), чтобы описать, как он продолжает запечатывание, инициированное его суперклассом

окончательный

  // close, dun extends me
  public final class LoginCommand implements Command{
  }

запечатанный

  // another sealed class
  // sealed class must have subclasses
  public sealed class LogoutCommand implements Command
        permits LogoutAndDeleteCachedCommand {
  }
  // Sealed this class again if you want
  public final class LogoutAndDeleteCachedCommand extends LogoutCommand {
  }

не запечатанный

  // open...up to you to play this
  // Create custom plugin by extending this class
  public non-sealed class PluginCommand implements Command {
  }

Примечание Вы заметили ключевое слово не запечатанный ? Я думаю, что это первое ключевое слово с дефисом в Java. Однако это функция предварительного просмотра; ключевое слово может измениться в будущем выпуске.

2.4 Этот запечатанный класс или разрешенные подклассы и соответствие образцу |/.

  switch (command) {
      case LoginCommand:      // login
      case LogoutCommand:     // logout
      case PluginCommand:     // custom plugin
      // no default needed, only permits 3 sub-classes
  }

P.S Запечатанный класс имеет второй предварительный просмотр в Java 16, JEP 397 .

Дальнейшее чтение

3. JEP 371: Скрытые Классы

3.1 В этом JEEP представлены скрытые классы, которые невозможно обнаружить и которые имеют ограниченный жизненный цикл (более короткий срок службы), что хорошо для разработчиков, которые динамически генерируют классы во время выполнения. И теперь мы можем использовать этот новый Поиск::определение скрытого класса API для создания скрытого класса или интерфейса из байтов.

3.2 Пример кода для использования определения скрытого класса для создания скрытого класса из класса с кодировкой Base64 и запуска статического метода поиска вручную.

package com.mkyong.java15.jep371;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Base64;

public class LookupProxyTest {

    //Here is the Base64 encoded class.
    /*
    package com.mkyong.java15.jep371;

    public class LookUpProxy{

        public static Integer lookup() {
            return 1;
        }
    }*/
    static final String CLASS_IN_BASE64 =
            "yv66vgAAADcAFQoABAANCgAOAA8HABAHABEBAAY8aW5pdD4BAAMoKV" +
            "YBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAGbG9va3VwAQAVKClM" +
            "amF2YS9sYW5nL0ludGVnZXI7AQAKU291cmNlRmlsZQEAEExvb2tVcF" +
            "Byb3h5LmphdmEMAAUABgcAEgwAEwAUAQAkY29tL21reW9uZy9qYXZh" +
            "MTUvamVwMzcxL0xvb2tVcFByb3h5AQAQamF2YS9sYW5nL09iamVjdA" +
            "EAEWphdmEvbGFuZy9JbnRlZ2VyAQAHdmFsdWVPZgEAFihJKUxqYXZh" +
            "L2xhbmcvSW50ZWdlcjsAIQADAAQAAAAAAAIAAQAFAAYAAQAHAAAAHQ" +
            "ABAAEAAAAFKrcAAbEAAAABAAgAAAAGAAEAAAADAAkACQAKAAEABwAA" +
            "AB0AAQAAAAAABQS4AAKwAAAAAQAIAAAABgABAAAABgABAAsAAAACAAw=";

    public static void main(String[] args) throws Throwable {

        //byte[] array = Files.readAllBytes(
        //      Paths.get("/home/mkyong/test/LookUpProxy.class"));
        //String s = Base64.getEncoder().encodeToString(array);
        //System.out.println(s);

        testHiddenClass();

    }

    // create a hidden class and run its static method
    public static void testHiddenClass() throws Throwable {

        byte[] classInBytes = Base64.getDecoder().decode(CLASS_IN_BASE64);

        Class proxy = MethodHandles.lookup()
                .defineHiddenClass(classInBytes,
                        true, MethodHandles.Lookup.ClassOption.NESTMATE)
                .lookupClass();

        // output: com.mkyong.java15.jep371.LookUpProxy/0x0000000800b94440
        System.out.println(proxy.getName());

        MethodHandle mh = MethodHandles.lookup().findStatic(proxy,
                "lookup",
                MethodType.methodType(Integer.class));

        Integer status = (Integer) mh.invokeExact();
        System.out.println(status);

    }

}

Выход

com.mkyong.java15.jep371.LookUpProxy/0x0000000800b94440
1

3.3 Этот JEP также устарел Unsafe.defineanonymousclass API и пометил его для удаления в будущем. Пожалуйста, больше не используйте этот API.

  byte[] classInBytes = Base64.getDecoder().decode(CLASS_IN_BASE64);

  Field theUnsafe = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
  theUnsafe.setAccessible(true);
  sun.misc.Unsafe unsafe = (sun.misc.Unsafe)theUnsafe.get(null);

  // @Deprecated(since = "15", forRemoval = false)
  Class proxy = unsafe.defineAnonymousClass(
          LookupProxyTest.class, classInBytes, null);

Дальнейшее чтение

4. JEP 372: Удалите движок JavaScript Nashorn

  • Java 8 JEP 174 представила Nashorn в качестве замены движка Javascript Rhino.
  • Java 11 JEP 335 устарел движок JavaScript Nashorn и jjs инструмент.
  • Теперь Java 15 навсегда удалила движок JavaScript Nashorn и инструмент jjs .

Этот JEP также удалил следующие два модуля:

  • jdk.scripting.nashorn – содержит jdk.nashorn.api.сценарии и jdk.nashorn.api.дерево пакеты.
  • jdk.scripting.nashorn.shell – содержит инструмент jjs.

Дальнейшее чтение

5. JEP 373: Переопределите устаревший API DatagramSocket

  • Java 13 JEP 353 переопределил устаревшие API сокетов – java.net . Гнездо и java.net . Серверный карман .
  • На этот раз Java 15 переопределила устаревшие API DatagramSocket – java.net . Датаграмсокет и java.net . Многоадресная рассылка .

Дальнейшее чтение

6. JEP 374: Отключить и запретить Смещенная блокировка

Этот JEP отключил и устарел блокировку со смещением по умолчанию. До Java 15 предвзятая блокировка всегда включалась по умолчанию, что давало прирост производительности для синхронизированного материала.

Более старое или устаревшее приложение Java использует API-интерфейсы синхронизации коллекций, такие как Hashtable и Вектор , а смещенная блокировка может повысить производительность. В настоящее время более новое приложение Java обычно использует несинхронизированные коллекции Хэш-карта и ArrayList , и прирост производительности от смещенной блокировки, как правило, сейчас менее полезен.

Однако для Java 15 мы все еще можем включить смещенную блокировку с помощью -XX:+Блокировка при использовании , но это вызовет предупреждение виртуальной машины для устаревшего API.

# Java 15
$ java -XX:+UseBiasedLocking name

 OpenJDK 64-Bit Server VM warning: Option UseBiasedLocking was deprecated
in version 15.0 and will likely be removed in a future release.

Дальнейшее чтение

7. JEP 375: Сопоставление с образцом, например (второй предварительный просмотр)

Java 14 JEP 305 введена Сопоставление с образцом в качестве функции предварительного просмотра. Этот JEP представляет собой второй предварительный просмотр сопоставления шаблонов для получения дополнительной обратной связи без изменений в API.

Типичный instanceof-и-приведение для проверки типа объекта и приведения его.

  private static void print(Object obj) {

      if (obj instanceof String) {        // instanceof

          String s = (String) obj;        // cast

          if ("java15".equalsIgnoreCase(s)) {
              System.out.println("Hello Java 15");
          }

      } else {
          System.out.println("not a string");
      }

  }

Для сопоставления с образцом мы можем проверять, отбрасывать и привязывать в одной строке.

  private static void printWithPatternMatching(Object obj) {

      // instanceof, cast and bind variable in one line.
      if (obj instanceof String s) {         

          if ("java15".equalsIgnoreCase(s)) {
              System.out.println("Hello Java 15");
          }

      } else {
          System.out.println("not a string");
      }

  }

P.S Сопоставление с образцом является стандартной функцией в Java 16, JEP 394 .

Дальнейшее чтение

8. JEP 377: ZGC: Масштабируемый Сборщик Мусора с Низкой задержкой

Java 11 JEP 333 представила сборщик мусора GC в качестве экспериментальной функции.

  • Этот JEEP исправил некоторые ошибки, добавил некоторые функции и улучшения и теперь поддерживает основные платформы, такие как Linux/x86_64, Linux/aarch64, Windows и macOS.
  • Этот JEP также превращает сборщик мусора Z из экспериментальной функции в функцию продукта. Однако сборщик мусора по умолчанию остается G1 .

Приведенная ниже команда включает сборщик мусора GC.

$ java -XX:+UseZGC className

Дальнейшее чтение

9. JEP 378: Текстовые блоки

Наконец, многострочные строки или текстовые блоки являются постоянной функцией в Java 15.

История:

Пример кода.

  String html = "\n" +
                "   \n" +
                "      

Hello, World

\n" + " \n" + "\n"; String java15 = """

Hello, World

""";

Дальнейшее чтение

10. JEP 379: Шенандоа: Сборщик мусора с низким временем паузы

Java 12 JEP 189 представил сборщик мусора Шенандоа в качестве экспериментальной функции, а теперь стал функцией продукта в Java 15.

До Java 15 нам нужно -XX:+Разблокируйте экспериментальные возможности --XX:+Используйте ГК Шенандоа чтобы включить GC Шенандоа.

java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

В Java 15 нам нужно только --XX:+Используйте GC Шенандоа для включения GC Шенандоа.

java -XX:+UseShenandoahGC

Однако официальная сборка OpenJDK 15 не включала GC Shenandoah (точно так же, как это произошло в Java 12). Прочитайте эту историю – Не все сборки OpenJDK 12 включают Shenandoah: Вот почему .

$ java -XX:+UseShenandoahGC ClassName

  Error occurred during initialization of VM
  Option -XX:+UseShenandoahGC not supported

$ java -version

  openjdk version "15" 2020-09-15
  OpenJDK Runtime Environment (build 15+36-1562)
  OpenJDK 64-Bit Server VM (build 15+36-1562, mixed mode, sharing)

Чтобы попробовать Shenandoah GC, нам нужны другие сборки JDK, такие как AdoptOpenJDK .

$ java -XX:+UseShenandoahGC ClassName

$ java -version

  openjdk version "15" 2020-09-15
  OpenJDK Runtime Environment AdoptOpenJDK (build 15+36)
  OpenJDK 64-Bit Server VM AdoptOpenJDK (build 15+36, mixed mode, sharing)

P.S Сборщик мусора по умолчанию остается G1 .

Дальнейшее чтение

11. JEP 381: Удалите Solaris и SPARC Порты

Java 14 JEP 362 устарели порты Solaris/SPARC, Solaris/x64 и Linux/SPARC, и теперь они официально удалены в Java 15.

Дальнейшее чтение

12. JEP 383: API доступа к внешней памяти (второй инкубатор)

Java 14 JEP 370 представила новый API доступа к внешней памяти в качестве Инкубаторных модулей . Этот ДЖИП внес некоторые изменения в API, и он все еще будет находиться в модулях инкубатора.

Пример кода

import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemoryHandles;
import jdk.incubator.foreign.MemorySegment;

import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;

public class HelloForeignMemory {

    public static void main(String[] args) {

        VarHandle intHandle = MemoryHandles.varHandle(
            int.class, ByteOrder.nativeOrder());

        try (MemorySegment segment = MemorySegment.allocateNative(1024)) {

            MemoryAddress base = segment.baseAddress();

            // print memory address
            System.out.println(base);                 

            // set value 999 into the foreign memory
            intHandle.set(base, 999);                 

            // get the value from foreign memory
            System.out.println(intHandle.get(base));  

        }

    }

}

Нам нужно добавить --add-modules jdk.incubator.foreign , чтобы включить модули инкубатора jdk.incubator.foreign .

$ javac --add-modules jdk.incubator.foreign HelloForeignMemory.java

warning: using incubating module(s): jdk.incubator.foreign
1 warning


$ java --add-modules jdk.incubator.foreign HelloForeignMemory

WARNING: Using incubator modules: jdk.incubator.foreign
MemoryAddress{ region: MemorySegment{ id=0x27c908f5 limit: 1024 } offset=0x0 }
999

Дальнейшее чтение

13. JEP 384: Записи (второй предварительный просмотр)

Java 14 JEP 359 представила записи в качестве функции предварительного просмотра. Этот JEP расширил записи с помощью таких функций, как поддержка запечатанных типов, локальных записей, аннотаций к записям и API-интерфейсов отражения для записей.

13.1 Записи и запечатанные типы

public sealed interface Fruit permits Apple, Orange {}

record Apple() implements Fruit{}
record Orange() implements Fruit{}

13.2 Локальные записи – записи объявляются внутри метода.

Приведенный ниже фрагмент кода использует локальную запись для улучшения читаемости потоковых операций.

  List findTopMerchants(List merchants, int month) {

      // Local record
      record MerchantSales(Merchant merchant, double sales) {
      }

      return merchants.stream()
              .map(merchant -> new MerchantSales(merchant, computeSales(merchant, month)))
              .sorted((m1, m2) -> Double.compare(m2.sales(), m1.sales()))
              .map(MerchantSales::merchant)
              .collect(toList());
  }

  private double computeSales(Merchant merchant, int month) {
      // some business logic to get the sales...
      return ThreadLocalRandom.current().nextDouble(100, 10000);
  }

13.3 Примечания к записям

public record Game(@CustomAnno Rank rank) { ... }

13.4 API отражения

В java.lang. Класс добавлены два общедоступных метода:

  • Компонент записи[] Компоненты GetRecord()
  • логическое значение isRecord()

P.S Запись является стандартной функцией в Java 16, ДЖИП 395 .

Дальнейшее чтение

14. JEP 385: Отмените активацию RMI для удаления

Этот JEP исключил устаревший механизм активации |/RMI |/. Это не повлияет на другие части RMI.

Дальнейшее чтение

Скачать Исходный Код

$ клон git $ клон git

$ cd java-15

Рекомендации

Оригинал: “https://mkyong.com/java/what-is-new-in-java-15/”