Учебники

Java 9 — Краткое руководство

Java 9 — Обзор

JAVA 9 (aka jdk 1.9) — это основной выпуск разработки языка программирования JAVA. Его первоначальная версия была выпущена 21 сентября 2017 года. Основные цели выпуска Java 9 —

  • Сделать платформу JDK и Java Standard Edition модульной в том смысле, что она может быть хорошо масштабирована до небольших вычислительных устройств.

  • Повысить общую безопасность JDK и Java-реализаций.

  • Упростить процесс сборки и сопровождения библиотек кода Java и больших приложений для платформ JAVA SE и EE.

  • Разработать и внедрить стандартную модульную систему для платформы Java, которую можно легко применять как на платформе, так и в JDK.

Сделать платформу JDK и Java Standard Edition модульной в том смысле, что она может быть хорошо масштабирована до небольших вычислительных устройств.

Повысить общую безопасность JDK и Java-реализаций.

Упростить процесс сборки и сопровождения библиотек кода Java и больших приложений для платформ JAVA SE и EE.

Разработать и внедрить стандартную модульную систему для платформы Java, которую можно легко применять как на платформе, так и в JDK.

Новые возможности

В Java 8 добавлено более 90 улучшений, наиболее значимые из которых перечислены ниже:

  • Модуль — новый вид компонента программирования Java, представленный в виде модуля, который представляет собой именованный, самоописываемый набор кода и данных.

  • REPL (JShell) — добавлена ​​возможность чтения-Eval-Print Loop (REPL) для платформы Java.

  • HTTP 2 Client — новый HTTPClient API, поддерживающий веб-сокеты и HTTP 2-потоки, а также функции проталкивания сервера.

  • Улучшенный JavaDocs — поддерживает генерацию вывода HTML5. Предоставляет окно поиска для сгенерированной документации API.

  • Multirelease JARрасширяет формат JAR, благодаря чему в одном архиве могут сосуществовать несколько версий файлов классов для конкретных версий Java.

  • Методы фабрики коллекций — Новые статические фабричные методы для интерфейсов List, Set и Map для создания неизменяемых экземпляров этих коллекций.

  • Методы частного интерфейса — расширенные интерфейсы с частными и частными статическими методами.

  • Улучшения API процессов — Улучшенный API для контроля и управления процессами операционной системы.

  • Усовершенствования Stream API — Повышенная безопасность и надежность благодаря возможности фильтрации входящих потоков данных сериализации объектов.

  • Улучшение Try With Resources — теперь конечные переменные можно использовать в качестве ресурсов в выражении try-with-resources.

  • Улучшенная аннотация @Deprecated — обновлена ​​аннотация @Deprecated для предоставления дополнительной информации о состоянии и предполагаемом расположении API.

  • Оператор Diamond внутреннего класса — разрешить использование оператора diamond с анонимными классами, если можно указать тип аргумента предполагаемого типа.

  • Необязательные улучшения класса — Новые полезные методы добавлены в класс java.util.Optional.

  • Multiresolution Image API — поддерживает инкапсуляцию набора изображений с разными разрешениями в одно изображение с множественным разрешением.

  • Усовершенствования API CompletableFuture . Асинхронные механизмы класса CompletableFuture могут выполнять действие при выходе из процесса с помощью метода ProcessHandle.onExit.

  • Облегченный JSON — упрощенный API, представленный для использования и создания документов и потоков данных через json в java 9.

  • API Reactive Streams — В Java SE 9 был представлен новый API Reactive Streams для поддержки реактивного программирования в Java 9.

Модуль — новый вид компонента программирования Java, представленный в виде модуля, который представляет собой именованный, самоописываемый набор кода и данных.

REPL (JShell) — добавлена ​​возможность чтения-Eval-Print Loop (REPL) для платформы Java.

HTTP 2 Client — новый HTTPClient API, поддерживающий веб-сокеты и HTTP 2-потоки, а также функции проталкивания сервера.

Улучшенный JavaDocs — поддерживает генерацию вывода HTML5. Предоставляет окно поиска для сгенерированной документации API.

Multirelease JARрасширяет формат JAR, благодаря чему в одном архиве могут сосуществовать несколько версий файлов классов для конкретных версий Java.

Методы фабрики коллекций — Новые статические фабричные методы для интерфейсов List, Set и Map для создания неизменяемых экземпляров этих коллекций.

Методы частного интерфейса — расширенные интерфейсы с частными и частными статическими методами.

Улучшения API процессов — Улучшенный API для контроля и управления процессами операционной системы.

Усовершенствования Stream API — Повышенная безопасность и надежность благодаря возможности фильтрации входящих потоков данных сериализации объектов.

Улучшение Try With Resources — теперь конечные переменные можно использовать в качестве ресурсов в выражении try-with-resources.

Улучшенная аннотация @Deprecated — обновлена ​​аннотация @Deprecated для предоставления дополнительной информации о состоянии и предполагаемом расположении API.

Оператор Diamond внутреннего класса — разрешить использование оператора diamond с анонимными классами, если можно указать тип аргумента предполагаемого типа.

Необязательные улучшения класса — Новые полезные методы добавлены в класс java.util.Optional.

Multiresolution Image API — поддерживает инкапсуляцию набора изображений с разными разрешениями в одно изображение с множественным разрешением.

Усовершенствования API CompletableFuture . Асинхронные механизмы класса CompletableFuture могут выполнять действие при выходе из процесса с помощью метода ProcessHandle.onExit.

Облегченный JSON — упрощенный API, представленный для использования и создания документов и потоков данных через json в java 9.

API Reactive Streams — В Java SE 9 был представлен новый API Reactive Streams для поддержки реактивного программирования в Java 9.

Java 9 — Настройка среды

Настройка локальной среды

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

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

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

Настройка пути для Windows 2000 / XP

Предполагая, что вы установили Java в каталог c: \ Program Files \ java \ jdk —

  • Щелкните правой кнопкой мыши «Мой компьютер» и выберите «Свойства».

  • Нажмите кнопку «Переменные среды» на вкладке «Дополнительно».

  • Теперь отредактируйте переменную ‘Path’ и добавьте путь к исполняемому каталогу Java в конце. Например, если путь в настоящее время установлен в C:\Windows\System32 , отредактируйте его следующим образом

Щелкните правой кнопкой мыши «Мой компьютер» и выберите «Свойства».

Нажмите кнопку «Переменные среды» на вкладке «Дополнительно».

Теперь отредактируйте переменную ‘Path’ и добавьте путь к исполняемому каталогу Java в конце. Например, если путь в настоящее время установлен в C:\Windows\System32 , отредактируйте его следующим образом

C:\Windows\System32;c:\Program Files\java\jdk\bin

Настройка пути для Windows 95/98 / ME

Предполагая, что вы установили Java в каталог c: \ Program Files \ java \ jdk —

  • Отредактируйте файл ‘C: \ autoexec.bat’ и добавьте следующую строку в конце:

Отредактируйте файл ‘C: \ autoexec.bat’ и добавьте следующую строку в конце:

SET PATH = %PATH%;C:\Program Files\java\jdk\bin

Настройка пути для Linux, UNIX, Solaris, FreeBSD

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

Например, если вы используете bash в качестве оболочки, вы добавите следующую строку в конец вашего .bashrc

export PATH = /path/to/java:$PATH'

Популярные редакторы Java

Чтобы писать программы на Java, вам нужен текстовый редактор. На рынке доступны еще более сложные IDE. Самые популярные из них кратко описаны ниже —

  • Блокнот — на компьютере с Windows вы можете использовать любой простой текстовый редактор, например Блокнот (рекомендуется для этого урока) или WordPad. Notepad ++ — это также бесплатный текстовый редактор, который расширил возможности.

  • Netbeans — это Java IDE с открытым исходным кодом, который можно загрузить по адресу https://www.netbeans.org/index.html .

  • Eclipse — это также Java IDE, разработанная сообществом открытого исходного кода Eclipse, которую можно загрузить по адресу https://www.eclipse.org/ .

Блокнот — на компьютере с Windows вы можете использовать любой простой текстовый редактор, например Блокнот (рекомендуется для этого урока) или WordPad. Notepad ++ — это также бесплатный текстовый редактор, который расширил возможности.

Netbeans — это Java IDE с открытым исходным кодом, который можно загрузить по адресу https://www.netbeans.org/index.html .

Eclipse — это также Java IDE, разработанная сообществом открытого исходного кода Eclipse, которую можно загрузить по адресу https://www.eclipse.org/ .

IDE или интегрированная среда разработки, предоставляет все общие инструменты и средства для помощи в программировании, такие как редактор исходного кода, инструменты сборки и отладчики и т. Д.

Java 9 — модульная система

Java 9, новый вид программного компонента под названием модуль был представлен. Модуль представляет собой самоописываемую коллекцию кода и данных и имеет имя для его идентификации.

Характеристики

С компонентом Modules в Java 9 были добавлены следующие улучшения:

  • Введен новый необязательный этап — время соединения. Эта фаза находится между временем компиляции и временем выполнения. На этом этапе можно собрать и оптимизировать набор модулей, создавая собственный образ среды выполнения с помощью инструмента jlink.

  • javac, jlink и java имеют дополнительные параметры для указания путей к модулям, которые дополнительно определяют местоположение модулей.

  • Формат JAR обновлен как модульный JAR, который содержит файл module-info.class в своем корневом каталоге.

  • Представлен формат JMOD, формат упаковки (похожий на JAR), который может включать собственный код и файлы конфигурации.

Введен новый необязательный этап — время соединения. Эта фаза находится между временем компиляции и временем выполнения. На этом этапе можно собрать и оптимизировать набор модулей, создавая собственный образ среды выполнения с помощью инструмента jlink.

javac, jlink и java имеют дополнительные параметры для указания путей к модулям, которые дополнительно определяют местоположение модулей.

Формат JAR обновлен как модульный JAR, который содержит файл module-info.class в своем корневом каталоге.

Представлен формат JMOD, формат упаковки (похожий на JAR), который может включать собственный код и файлы конфигурации.

Создание модуля

Следуя инструкциям по созданию модуля, скажите com.tutorialspoint.greetings.

Шаг 1

Создайте папку C: \> JAVA \ src. Теперь создайте папку com.tutorialspoint.greetings, которая совпадает с именем создаваемого нами модуля.

Шаг 2

Создайте module-info.java в папке C: \> JAVA \ src \ com.tutorialspoint.greetings со следующим кодом.

module-info.java

module com.tutorialspoint.greetings { }

module-info.java — это файл, который используется для создания модуля. На этом этапе мы создали модуль с именем com.tutorialspoint.greetings. По договоренности этот файл должен находиться в папке, имя которой совпадает с именем модуля.

Шаг 3

Добавьте исходный код в модуль. Создайте Java9Tester.java в папке C: \> JAVA \ src \ com.tutorialspoint.greetings \ com \ tutorialspoint \ greetings со следующим кодом.

Java9Tester.java

package com.tutorialspoint.greetings;

public class Java9Tester {
   public static void main(String[] args) {
      System.out.println("Hello World!");
   }
}

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

Шаг 4

Создайте папку C: \> JAVA \ mods. Теперь создайте папку com.tutorialspoint.greetings, которая совпадает с именем созданного нами модуля. Теперь скомпилируйте модуль в каталог модов.

C:/ > JAVA > javac -d mods/com.tutorialspoint.greetings 
   src/com.tutorialspoint.greetings/module-info.java 
   src/com.tutorialspoint.greetings/com/tutorialspoint/greetings/Java9Tester.java

Шаг 5

Давайте запустим модуль, чтобы увидеть результат. Запустите следующую команду.

C:/ > JAVA > java --module-path mods -m com.tutorialspoint.greetings/com.tutorialspoint.greetings.Java9Tester

Здесь module-path предоставляет расположение модуля в виде модов, а -m обозначает основной модуль.

Выход

Он выведет следующий вывод на консоль.

Hello World!

Java 9 — REPL (JShell)

REPL расшифровывается как Read-Eval-Print Loop. С JShell, Java имеет возможность REPL. Используя REPL, мы можем кодировать и тестировать логику на основе Java без компиляции с использованием javac и напрямую видеть результат вычислений.

Запуск JShell

Откройте командную строку и введите jshell.

$ jshell
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro
jshell>

Просмотр команд JShell

Введите / help после запуска команды jshell.

jshell> /help
|  Type a Java language expression, statement, or declaration.
|  Or type one of the following commands:
|  /list [<name or id>|-all|-start]
|  list the source you have typed
|  /edit <name or id>
|  edit a source entry referenced by name or id
|  /drop <name or id>
|  delete a source entry referenced by name or id
|  /save [-all|-history|-start] <file>
|  Save snippet source to a file.
|  /open <file>
|  open a file as source input
|  /vars [<name or id>|-all|-start]
|  list the declared variables and their values
|  /methods [<name or id>|-all|-start]
|  list the declared methods and their signatures
|  /types [<name or id>|-all|-start]
|  list the declared types
|  /imports 
|  list the imported items

Запуск команды JShell

После запуска команды jshell введите / import и просмотрите список использованных импортов.

jshell> /imports
|    import java.io.*
|    import java.math.*
|    import java.net.*
|    import java.nio.file.*
|    import java.util.*
|    import java.util.concurrent.*
|    import java.util.function.*
|    import java.util.prefs.*
|    import java.util.regex.*
|    import java.util.stream.*
jshell>

Выполнение расчетов в JShell.

Попробуйте выполнить простые вычисления в JShell.

jshell> 3+1
$1 ==> 4
jshell> 13%7
$2 ==> 6
jshell> $2
$2 ==> 6
jshell>

Создание и использование функций в JShell

Создайте функцию doubled (), чтобы взять int и вернуть его удвоенное значение.

jshell> int doubled(int i){ return i*2;}
|  created method doubled(int)
jshell> doubled(6)
$3 ==> 12
jshell>

Выход из JShell

Тип / выход.

jshell> /exit
| Goodbye

Java 9 — улучшенные JavaDocs

Документация по Java может быть сгенерирована с использованием инструмента javadoc. В настоящее время он генерирует документацию в формате html 4.0. В java 9 мы можем генерировать документацию в формате html 5, используя опцию -html5 в аргументах командной строки.

Документация Java старого стиля

Рассмотрим следующий код в папке C: / JAVA.

Tester.java

Live Demo

/**
 * @author MahKumar
 * @version 0.1
 */
public class Tester {
   /**
   * Default method to be run to print 
   * <p>Hello world</p>
   * @param args command line arguments
   */
   public static void main(String []args) {
      System.out.println("Hello World");
   }
}

Теперь запустите инструмент javadoc из jdk 7, чтобы сгенерировать документацию.

C:\JAVA>javadoc -d C:/JAVA Tester.java
Loading source file tester.java...
Constructing Javadoc information...
Standard Doclet version 1.7.0_21
Building tree for all the packages and classes...
Generating C:\JAVA\Tester.html...
Generating C:\JAVA\package-frame.html...
Generating C:\JAVA\package-summary.html...
Generating C:\JAVA\package-tree.html...
Generating C:\JAVA\constant-values.html...
Building index for all the packages and classes...
Generating C:\JAVA\overview-tree.html...
Generating C:\JAVA\index-all.html...
Generating C:\JAVA\deprecated-list.html...
Building index for all classes...
Generating C:\JAVA\allclasses-frame.html...
Generating C:\JAVA\allclasses-noframe.html...
Generating C:\JAVA\index.html...
Generating C:\JAVA\help-doc.html...

Он создаст страницу документации Java в каталоге C: / JAVA, и вы увидите следующий вывод.

вывод Javadoc

Новая документация Java с поиском и поддержкой HTML5

Запустите инструмент javadoc из jdk 9 с флагом -html5, чтобы сгенерировать новый тип документации.

C:\JAVA> javadoc -d C:/JAVA -html5 Tester.java
Loading source file Tester.java...
Constructing Javadoc information...
Standard Doclet version 9.0.1
Building tree for all the packages and classes...
Generating C:\JAVA\Tester.html...
Generating C:\JAVA\package-frame.html...
Generating C:\JAVA\package-summary.html...
Generating C:\JAVA\package-tree.html...
Generating C:\JAVA\constant-values.html...
Building index for all the packages and classes...
Generating C:\JAVA\overview-tree.html...
Generating C:\JAVA\index-all.html...
Generating C:\JAVA\deprecated-list.html...
Building index for all classes...
Generating C:\JAVA\allclasses-frame.html...
Generating C:\JAVA\allclasses-frame.html...
Generating C:\JAVA\allclasses-noframe.html...
Generating C:\JAVA\allclasses-noframe.html...
Generating C:\JAVA\index.html...
Generating C:\JAVA\help-doc.html...

Он создаст обновленную страницу документации Java в каталоге D: / test, и вы увидите следующий вывод.

вывод javadoc в java 9

Java 9 — мультирелизный JAR

В java 9 появилась новая функция, в которой был улучшен формат jar, чтобы иметь возможность поддерживать и использовать разные версии java-класса или ресурсы в соответствии с платформой. В JAR файл MANIFEST.MF имеет запись Multi-Release: true в своем основном разделе. Каталог META-INF также содержит подкаталог версий, подкаталоги которого (начиная с 9 для Java 9) содержат классы, зависящие от версии, и файлы ресурсов.

В этом примере мы будем использовать jar с несколькими выпусками, чтобы иметь две версии файла Tester.java, одну для jdk 7 и одну для jdk 9, и запускать его в разных версиях jdk.

меры

Шаг 1 — Создайте папку c: / test / java7 / com / tutorialspoint. Создать Test.java со следующим содержанием —

Tester.java

Live Demo

package com.tutorialspoint;

public class Tester {
   public static void main(String[] args) {
      System.out.println("Inside java 7");
   }
}

Шаг 2 — Создайте папку c: / test / java9 / com / tutorialspoint. Создать Test.java со следующим содержанием —

Tester.java

Live Demo

package com.tutorialspoint;

public class Tester {
   public static void main(String[] args) {
      System.out.println("Inside java 9");
   }
}

Скомпилируйте исходные коды.

C:\test > javac --release 9 java9/com/tutorialspoint/Tester.java

C:\JAVA > javac --release 7 java7/com/tutorialspoint/Tester.java

Создать мульти-релиз банку

C:\JAVA > jar -c -f test.jar -C java7 . --release 9 -C java9.
Warning: entry META-INF/versions/9/com/tutorialspoint/Tester.java, 
   multiple resources with same name

Запустить с JDK 7

C:\JAVA > java -cp test.jar com.tutorialspoint.Tester
Inside Java 7

Беги с JDK 9

C:\JAVA > java -cp test.jar com.tutorialspoint.Tester
Inside Java 9

Java 9 — методы фабрики коллекций

В Java 9 новые фабричные методы добавляются в интерфейсы List, Set и Map для создания неизменяемых экземпляров. Эти фабричные методы являются удобными фабричными методами для создания коллекции менее подробным и кратким способом.

Старый способ создания коллекций

Live Demo

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Tester {

   public static void main(String []args) {
      Set<String> set = new HashSet<>();
      set.add("A");
      set.add("B");
      set.add("C");
      set = Collections.unmodifiableSet(set);
      System.out.println(set);
      List<String> list = new ArrayList<>();

      list.add("A");
      list.add("B");
      list.add("C");
      list = Collections.unmodifiableList(list);
      System.out.println(list);
      Map<String, String> map = new HashMap<>();

      map.put("A","Apple");
      map.put("B","Boy");
      map.put("C","Cat");
      map = Collections.unmodifiableMap(map);
      System.out.println(map);
   }
}

Выход

Он напечатает следующий вывод.

 [A, B, C]
 [A, B, C]
 {A = Apple, B = Мальчик, C = Кошка}

Новые Методы

С java 9 следующие методы добавляются в интерфейсы List, Set и Map вместе с их перегруженными аналогами.

static <E> List<E> of(E e1, E e2, E e3);
static <E> Set<E>  of(E e1, E e2, E e3);
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3);
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)

Указывает на заметку

  • Для интерфейсов List и Set метод of (…) перегружен, чтобы иметь от 0 до 10 параметров и один с параметром var args.

  • Для интерфейса Map метод of (…) перегружен и имеет от 0 до 10 параметров.

  • Если для интерфейса Map более 10 параметров, можно использовать метод ofEntries (…), принимающий параметр var args.

Для интерфейсов List и Set метод of (…) перегружен, чтобы иметь от 0 до 10 параметров и один с параметром var args.

Для интерфейса Map метод of (…) перегружен и имеет от 0 до 10 параметров.

Если для интерфейса Map более 10 параметров, можно использовать метод ofEntries (…), принимающий параметр var args.

Новый способ создания коллекций

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Set;

public class Tester {

   public static void main(String []args) {
      Set<String> set = Set.of("A", "B", "C");      
      System.out.println(set);
      List<String> list = List.of("A", "B", "C");
      System.out.println(list);
      Map<String, String> map = Map.of("A","Apple","B","Boy","C","Cat");
      System.out.println(map);
  
      Map<String, String> map1 = Map.ofEntries (
         new AbstractMap.SimpleEntry<>("A","Apple"),
         new AbstractMap.SimpleEntry<>("B","Boy"),
         new AbstractMap.SimpleEntry<>("C","Cat"));
      System.out.println(map1);
   }
}

Выход

Он напечатает следующий вывод.

 [A, B, C]
 [A, B, C]
 {A = Apple, B = Мальчик, C = Кошка}
 {A = Apple, B = Мальчик, C = Кошка}

Java 9 — методы частного интерфейса

До Java 8 интерфейсы могут иметь следующий тип переменных / методов.

  • Постоянные переменные
  • Абстрактные методы

Поэтому у нас не может быть реализации метода в интерфейсах или, точнее, реализации по умолчанию до Java 8. См. Пример.

Live Demo

public class Tester {
   public static void main(String []args) {
      LogOracle log = new LogOracle();
      log.logInfo("");
      log.logWarn("");
      log.logError("");
      log.logFatal("");
      LogMySql log1 = new LogMySql();
      log1.logInfo("");
      log1.logWarn("");
      log1.logError("");
      log1.logFatal("");
   }
}

final class LogOracle implements Logging {
   @Override
   public void logInfo(String message) {
      getConnection();
      System.out.println("Log Message : " + "INFO");
      closeConnection();
   }

   @Override
   public void logWarn(String message) {
      getConnection();
      System.out.println("Log Message : " + "WARN");
      closeConnection();
   }

   @Override
   public void logError(String message) {
      getConnection();
      System.out.println("Log Message : " + "ERROR");
      closeConnection();
   }

   @Override
   public void logFatal(String message) {
      getConnection();
      System.out.println("Log Message : " + "FATAL");
      closeConnection();
   }

   @Override
   public void getConnection() {
      System.out.println("Open Database connection");
   }

   @Override
   public void closeConnection() {
      System.out.println("Close Database connection");
   }
}

final class LogMySql implements Logging {
   @Override
   public void logInfo(String message) {
      getConnection();
      System.out.println("Log Message : " + "INFO");
      closeConnection();
   }

   @Override
   public void logWarn(String message) {
      getConnection();
      System.out.println("Log Message : " + "WARN");
      closeConnection();
   }

   @Override
   public void logError(String message) {
      getConnection();
      System.out.println("Log Message : " + "ERROR");
      closeConnection();
   }

   @Override
   public void logFatal(String message) {
      getConnection();
      System.out.println("Log Message : " + "FATAL");
      closeConnection();
   }

   @Override
   public void getConnection() {
      System.out.println("Open Database connection");
   }

   @Override
   public void closeConnection() {
      System.out.println("Close Database connection");
   }
}

interface Logging {
   String ORACLE = "Oracle_Database";
   String MYSQL = "MySql_Database";

   void logInfo(String message);
   void logWarn(String message);
   void logError(String message);
   void logFatal(String message);

   void getConnection();
   void closeConnection();
}

Выход

Вы увидите следующий вывод.

Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection

В приведенном выше примере каждый метод журнала имеет свою реализацию. В Java 8 интерфейсы могут иметь следующий тип переменных / методов.

  • Постоянные переменные
  • Абстрактные методы
  • Методы по умолчанию
  • Статические методы

Давайте иметь реализацию по умолчанию и статические методы в самом интерфейсе, используя Java 8.

Live Demo

public class Tester {
   public static void main(String []args) {
      LogOracle log = new LogOracle();
      log.logInfo("");
      log.logWarn("");
      log.logError("");
      log.logFatal("");
      LogMySql log1 = new LogMySql();
      log1.logInfo("");
      log1.logWarn("");
      log1.logError("");
      log1.logFatal("");
   }
}

final class LogOracle implements Logging { 
}

final class LogMySql implements Logging { 
}

interface Logging {
   String ORACLE = "Oracle_Database";
   String MYSQL = "MySql_Database";

   default void logInfo(String message) {
      getConnection();
      System.out.println("Log Message : " + "INFO");
      closeConnection();
   }
   
   default void logWarn(String message) {
      getConnection();
      System.out.println("Log Message : " + "WARN");
      closeConnection();
   }
   
   default void logError(String message) {
      getConnection();
      System.out.println("Log Message : " + "ERROR");
      closeConnection();
   }
   
   default void logFatal(String message) {
      getConnection();
      System.out.println("Log Message : " + "FATAL");
      closeConnection();
   }

   static void getConnection() {
      System.out.println("Open Database connection");
   }
   static void closeConnection() {
      System.out.println("Close Database connection");
   }
}

Выход

Вы увидите следующий вывод.

Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection

В приведенном выше примере мы повторим снова. В Java 9 интерфейсы могут иметь следующий тип переменных / методов.

  • Постоянные переменные
  • Абстрактные методы
  • Методы по умолчанию
  • Статические методы
  • Частные методы
  • Частные статические методы

Давайте иметь частные методы и использовать их в Java 9.

public class Tester {
   public static void main(String []args) {
      LogOracle log = new LogOracle();
      log.logInfo("");
      log.logWarn("");
      log.logError("");
      log.logFatal("");
      LogMySql log1 = new LogMySql();
      log1.logInfo("");
      log1.logWarn("");
      log1.logError("");
      log1.logFatal("");
   }
}

final class LogOracle implements Logging { 
}

final class LogMySql implements Logging { 
}

interface Logging {
   String ORACLE = "Oracle_Database";
   String MYSQL = "MySql_Database";

   private void log(String message, String prefix) {
      getConnection();
      System.out.println("Log Message : " + prefix);
      closeConnection();
   }
   
   default void logInfo(String message) {
      log(message, "INFO");
   }
   
   default void logWarn(String message) {
      log(message, "WARN");
   }
   
   default void logError(String message) {
      log(message, "ERROR");
   }
   
   default void logFatal(String message) {
      log(message, "FATAL");
   }

   private static void getConnection() {
      System.out.println("Open Database connection");
   }
   
   private static void closeConnection() {
      System.out.println("Close Database connection");
   }
}

Выход

Вы увидите следующий вывод.

Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection

Java 9 — улучшения API процесса

В Java 9 Process API, который отвечает за контроль и управление процессами операционной системы, был значительно улучшен. Класс ProcessHandle теперь предоставляет собственный идентификатор процесса, время запуска, накопленное время процессора, аргументы, команду, пользователя, родительский процесс и потомков. Класс ProcessHandle также предоставляет метод для проверки жизнеспособности процессов и их уничтожения. Он имеет метод onExit, класс CompletableFuture может выполнять действие асинхронно при выходе из процесса.

Tester.java

import java.time.ZoneId;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.io.IOException;

public class Tester {
   public static void main(String[] args) throws IOException {
      ProcessBuilder pb = new ProcessBuilder("notepad.exe");
      String np = "Not Present";
      Process p = pb.start();
      ProcessHandle.Info info = p.info();
      System.out.printf("Process ID : %s%n", p.pid());
      System.out.printf("Command name : %s%n", info.command().orElse(np));
      System.out.printf("Command line : %s%n", info.commandLine().orElse(np));

      System.out.printf("Start time: %s%n",
         info.startInstant().map(i -> i.atZone(ZoneId.systemDefault())
         .toLocalDateTime().toString()).orElse(np));

      System.out.printf("Arguments : %s%n",
         info.arguments().map(a -> Stream.of(a).collect(
            Collectors.joining(" "))).orElse(np));

      System.out.printf("User : %s%n", info.user().orElse(np));
   } 
}

Выход

Вы увидите следующий вывод.

Process ID : 5800
Command name : C:\Windows\System32\notepad.exe
Command line : Not Present
Start time: 2017-11-04T21:35:03.626
Arguments : Not Present
User: administrator

Java 9 — Улучшения потокового API

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

takeWhile (интерфейс предиката)

Синтаксис

default Stream<T> takeWhile(Predicate<? super T> predicate)

Метод takeWhile принимает все значения, пока предикат не вернет false. В случае упорядоченного потока он возвращает поток, состоящий из самого длинного префикса элементов, взятых из этого потока, соответствующих данному предикату.

пример

import java.util.stream.Stream;

public class Tester {
   public static void main(String[] args) {
      Stream.of("a","b","c","","e","f").takeWhile(s->!s.isEmpty())
         .forEach(System.out::print);		 
   } 
}

Выход

Метод takeWhile принимает все значения a, b и c, затем, когда строка пуста, выполнение прекращается.

abc

dropWhile (интерфейс предиката)

Синтаксис

default Stream<T> dropWhile(Predicate<? super T> predicate)

Метод dropWhile отбрасывает все значения в начале, пока предикат не вернет true. В случае упорядоченного потока он возвращает поток, состоящий из оставшихся элементов этого потока, после удаления самого длинного префикса элементов, соответствующих данному предикату.

пример

import java.util.stream.Stream;

public class Tester {
   public static void main(String[] args) {
      Stream.of("a","b","c","","e","f").dropWhile(s-> !s.isEmpty())
      .forEach(System.out::print);
      System.out.println();
      Stream.of("a","b","c","","e","","f").dropWhile(s-> !s.isEmpty())
      .forEach(System.out::print);
   } 
}

Выход

Метод dropWhile сбрасывает значения a, b и c, затем, когда строка пуста, она принимает все значения.

ef
ef

повторять

Синтаксис

static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)

Метод iterate теперь имеет предикат hasNext в качестве параметра, который останавливает цикл, когда предикат hasNext возвращает false.

пример

import java.util.stream.IntStream;

public class Tester {
   public static void main(String[] args) {
      IntStream.iterate(3, x -> x < 10, x -> x+ 3).forEach(System.out::println);
   } 
}

Выход

3
6
9

ofNullable

Синтаксис

static <T> Stream<T> ofNullable(T t)

Метод ofNullable введен, чтобы предотвратить исключения NullPointerException и избежать нулевых проверок для потоков. Этот метод возвращает последовательный поток, содержащий один элемент, если он не равен нулю, в противном случае возвращает пустой поток.

пример

import java.util.stream.Stream;

public class Tester {
   public static void main(String[] args) {
      long count = Stream.ofNullable(100).count();
      System.out.println(count);
  
      count = Stream.ofNullable(null).count();
      System.out.println(count);
   } 
}

Выход

1
0

Java 9 — Попробуйте с улучшением ресурсов

Оператор try-with-resources является оператором try с одним или несколькими ресурсами, должным образом объявленными. Здесь ресурс — это объект, который должен быть закрыт, если он больше не требуется. Оператор try-with-resources обеспечивает закрытие каждого ресурса после завершения требования. Любой объект, реализующий интерфейс java.lang.AutoCloseable или java.io.Closeable, может быть использован в качестве ресурса.

До Java 9 ресурсы должны быть объявлены перед оператором try или внутри оператора try, как показано ниже в данном примере. В этом примере мы будем использовать BufferedReader в качестве ресурса для чтения строки, а затем BufferedReader должен быть закрыт.

Tester.java

Live Demo

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Tester {
   public static void main(String[] args) throws IOException {
      System.out.println(readData("test"));
   } 

   static String readData(String message) throws IOException {
      Reader inputString = new StringReader(message);
      BufferedReader br = new BufferedReader(inputString);
      try (BufferedReader br1 = br) {
         return br1.readLine();
      }
   }
}

Выход

test

Здесь нам нужно объявить ресурс br1 в try statment и затем использовать его. В Java9 нам больше не нужно объявлять br1, и следующая программа даст тот же результат.

Tester.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Tester {
   public static void main(String[] args) throws IOException {
      System.out.println(readData("test"));
   } 

   static String readData(String message) throws IOException {
      Reader inputString = new StringReader(message);
      BufferedReader br = new BufferedReader(inputString);
      try (br) {
         return br.readLine();
      }
   }
}

Выход

test

Java 9 — расширенная аннотация аннотации

@ Устаревшая аннотация была введена в версии Java 5. Программный элемент, помеченный @Deprecated, означает, что его нельзя использовать по любой из следующих причин:

  • Его использование может привести к ошибкам.
  • Это может быть несовместимо в будущей версии.
  • Это может быть удалено в будущей версии.
  • Лучшая и эффективная альтернатива превзошла его.

Компилятор генерирует предупреждения всякий раз, когда используется устаревший элемент. В Java 9 два новых улучшения внесены в аннотацию @Deprecated.

  • forRemoval — указывает, подлежит ли аннотированный элемент удалению в будущей версии. Значение по умолчанию неверно.

  • since — Возвращает версию, в которой аннотированный элемент устарел. Значением по умолчанию является пустая строка.

forRemoval — указывает, подлежит ли аннотированный элемент удалению в будущей версии. Значение по умолчанию неверно.

since — Возвращает версию, в которой аннотированный элемент устарел. Значением по умолчанию является пустая строка.

Устаревший с тех пор

Следующий пример логического класса javadoc на Java 9 иллюстрирует использование атрибута Since в аннотации @Deprecated.

Логический класс

Булевский класс javadoc

Устаревший с forRemoval

Следующий пример класса System javadoc на Java 9 иллюстрирует использование атрибута forRemoval в аннотации @Deprecated.

Системный класс

Системный класс Javadoc

Java 9 — Алмазный оператор внутреннего класса

Оператор Diamond был введен в Java 7, чтобы сделать код более читабельным, но его нельзя использовать с внутренними классами Anonymous. В java 9 его также можно использовать с анонимным классом, чтобы упростить код и улучшить читаемость. Рассмотрим следующий код до Java 9.

Tester.java

Live Demo

public class Tester {
   public static void main(String[] args) {
         Handler<Integer> intHandler = new Handler<Integer>(1) {
         
         @Override
         public void handle() {
            System.out.println(content);
         }
      };

      intHandler.handle();
      Handler<? extends Number> intHandler1 = new Handler<Number>(2) {
         
         @Override
         public void handle() {
            System.out.println(content);
         }
      };

      intHandler1.handle();
      Handler<?> handler = new Handler<Object>("test") {
         
         @Override
         public void handle() {
            System.out.println(content);
         }
      };

      handler.handle();    
   }  
}

abstract class Handler<T> {
   public T content;

   public Handler(T content) {
      this.content = content; 
   }
   
   abstract void handle();
}

Выход

1
2
Test

В Java 9 мы можем использовать оператор <> с анонимным классом, как показано ниже.

Tester.java

public class Tester {
   public static void main(String[] args) {
         Handler<Integer> intHandler = new Handler<>(1) {
         
         @Override
         public void handle() {
            System.out.println(content);
         }
      };

      intHandler.handle();
      Handler<? extends Number> intHandler1 = new Handler<>(2) {
         
         @Override
         public void handle() {
            System.out.println(content);
         }
      };

      intHandler1.handle();
      Handler<?> handler = new Handler<>("test") {
         
         @Override
         public void handle() {
            System.out.println(content);
         }
      };

      handler.handle();    
   }  
}

abstract class Handler<T> {
   public T content;

   public Handler(T content) {
      this.content = content; 
   }
   
   abstract void handle();
}

Выход

1
2
Test

Java 9 — Необязательные улучшения классов

Необязательный класс был введен в Java 8, чтобы избежать проверок NULL и проблем с NullPointerException. В java 9 добавлены три новых метода для улучшения его функциональности.

  • поток()
  • ifPresentOrElse ()
  • или же()

метод stream ()

Синтаксис

public Stream<T> stream()

Если значение присутствует, оно возвращает последовательный поток, содержащий только это значение, в противном случае возвращает пустой поток.

пример

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Tester {
public static void main(String[] args) {
   List<Optional<String>> list = Arrays.asList (
      Optional.empty(), 
      Optional.of("A"), 
      Optional.empty(), 
      Optional.of("B"));

   //filter the list based to print non-empty values
  
   //if optional is non-empty, get the value in stream, otherwise return empty
   List<String> filteredList = list.stream()
      .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())
      .collect(Collectors.toList());

   //Optional::stream method will return a stream of either one 
   //or zero element if data is present or not.
   List<String> filteredListJava9 = list.stream()
      .flatMap(Optional::stream)
      .collect(Collectors.toList());

      System.out.println(filteredList);
      System.out.println(filteredListJava9);
   }  
}

Выход

[A, B]
[A, B]

метод ifPresentOrElse ()

Синтаксис

public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)

Если значение присутствует, выполняет данное действие со значением, в противном случае выполняет данное пустое действие.

пример

import java.util.Optional;

public class Tester {
   public static void main(String[] args) {
      Optional<Integer> optional = Optional.of(1);

      optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() -> 
         System.out.println("Not Present."));

      optional = Optional.empty();

      optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() -> 
         System.out.println("Not Present."));
   }  
}

Выход

Value: 1
Not Present.

или () метод

Синтаксис

public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)

Если значение присутствует, возвращает Optional, описывающий значение, в противном случае возвращает Optional, созданный функцией предоставления.

пример

import java.util.Optional;
import java.util.function.Supplier;

public class Tester {
   public static void main(String[] args) {
      Optional<String> optional1 = Optional.of("Mahesh");

      Supplier<Optional<String>> supplierString = () -> Optional.of("Not Present");

      optional1 = optional1.or( supplierString);
  
      optional1.ifPresent( x -> System.out.println("Value: " + x));
    
      optional1 = Optional.empty();    

      optional1 = optional1.or( supplierString);
  
      optional1.ifPresent( x -> System.out.println("Value: " + x));  
   }  
}

Выход

Value: Mahesh
Value: Not Present

Java 9 — Multiresolution Image API

В Java 9 был представлен новый API изображений с несколькими разрешениями, который поддерживает несколько изображений с различными вариантами разрешения. Этот API позволяет использовать набор изображений с разным разрешением в качестве одного изображения с несколькими разрешениями. Ниже приведены основные операции с мульти-разрешением изображения.

  • Image getResolutionVariant (double destImageWidth, double destImageHeight) — получает конкретное изображение, которое является наилучшим вариантом для представления этого логического изображения в указанном размере.

  • List <Image> getResolutionVariants () — Получает читаемый список всех вариантов разрешения.

Image getResolutionVariant (double destImageWidth, double destImageHeight) — получает конкретное изображение, которое является наилучшим вариантом для представления этого логического изображения в указанном размере.

List <Image> getResolutionVariants () — Получает читаемый список всех вариантов разрешения.

пример

import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.awt.Image;
import java.awt.image.MultiResolutionImage;
import java.awt.image.BaseMultiResolutionImage;

import javax.imageio.ImageIO;

public class Tester {
   public static void main(String[] args) throws IOException, MalformedURLException {

      List<String> imgUrls = List.of("http://www.tutorialspoint.com/java9/images/logo.png",
         "http://www.tutorialspoint.com/java9/images/mini_logo.png",
         "http://www.tutorialspoint.com/java9/images/large_logo.png");

      List<Image> images = new ArrayList<Image>();

      for (String url : imgUrls) {
         images.add(ImageIO.read(new URL(url)));
      }

      // read all images into one multiresolution image
      MultiResolutionImage multiResolutionImage = 
         new BaseMultiResolutionImage(images.toArray(new Image[0]));

      // get all variants of images
      List<Image> variants = multiResolutionImage.getResolutionVariants();

      System.out.println("Total number of images: " + variants.size());

      for (Image img : variants) {
         System.out.println(img);
      }

      // get a resolution-specific image variant for each indicated size
      Image variant1 = multiResolutionImage.getResolutionVariant(156, 45);
      System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 
         156, 45, variant1.getWidth(null), variant1.getHeight(null));

      Image variant2 = multiResolutionImage.getResolutionVariant(311, 89);
      System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 311, 89, 
         variant2.getWidth(null), variant2.getHeight(null));

      Image variant3 = multiResolutionImage.getResolutionVariant(622, 178);
      System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 622, 178, 
         variant3.getWidth(null), variant3.getHeight(null));

      Image variant4 = multiResolutionImage.getResolutionVariant(300, 300);
      System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 300, 300, 
         variant4.getWidth(null), variant4.getHeight(null));
   }  
}

Выход

Total number of images: 3
BufferedImage@7ce6a65d: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 
color space =java.awt.color.ICC_ColorSpace@548ad73b transparency = 3 
has alpha = true isAlphaPre = false ByteInterleavedRaster: width =311 
height = 89 #numDataElements 4 dataOff[0] = 3

BufferedImage@4c762604: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 
color space =java.awt.color.ICC_ColorSpace@548ad73b transparency = 3 
has alpha = true isAlphaPre = false ByteInterleavedRaster: width =156 
height = 45 #numDataElements 4 dataOff[0] = 3

BufferedImage@2641e737: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 
color space =java.awt.color.ICC_ColorSpace@548ad73b transparency = 3 
has alpha = true isAlphaPre = false ByteInterleavedRaster: width =622 
height = 178 #numDataElements 4 dataOff[0] = 3

Image for destination[156,45]: [311,89]
Image for destination[311,89]: [311,89]
Image for destination[622,178]: [622,178]
Image for destination[300,300]: [622,178]

Усовершенствования API CompletableFuture

Класс CompletableFuture был введен в Java 8 для представления Future, которое можно завершить, задав его значение и статус статуса. Может использоваться как java.util.concurrent.CompletionStage. Он поддерживает зависимые функции и действия, которые были вызваны после завершения будущего. В Java 9 CompletableFuture API был улучшен еще больше. Ниже приведены соответствующие изменения, внесенные в API.

  • Поддержка задержек и тайм-аутов.
  • Улучшена поддержка подклассов.
  • Добавлены новые заводские методы.

Поддержка задержек и тайм-аутов

public CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)

Этот метод завершает это CompletableFuture с заданным значением, если иное не завершено до заданного времени ожидания.

public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)

Этот метод исключительно завершает это CompletableFuture с TimeoutException, если иное не завершено до заданного времени ожидания.

Улучшена поддержка подклассов

public Executor defaultExecutor()

Он возвращает Executor по умолчанию, используемый для асинхронных методов, которые не указывают Executor. Этот метод может быть переопределен в подклассах, чтобы возвратить Исполнителя как минимум для одного независимого потока.

public <U> CompletableFuture<U> newIncompleteFuture()

Возвращает новое незавершенное CompletableFuture типа, которое будет возвращено методом CompletionStage. Подклассы класса CompletableFuture должны переопределить этот метод, чтобы возвратить экземпляр того же класса, что и этот CompletableFuture. Реализация по умолчанию возвращает экземпляр класса CompletableFuture.

Новые фабричные методы

public static <U> CompletableFuture<U> completedFuture(U value)

Этот фабричный метод возвращает новое CompletableFuture, которое уже завершено с заданным значением.

public static <U> CompletionStage<U> completedStage(U value)

Этот фабричный метод возвращает новый CompletionStage, который уже завершен с заданным значением и поддерживает только те методы, которые присутствуют в интерфейсе CompletionStage.

public static <U> CompletionStage<U> failedStage(Throwable ex)

Этот фабричный метод возвращает новый CompletionStage, который уже завершен исключительно с данным исключением и поддерживает только те методы, которые присутствуют в интерфейсе CompletionStage.

Java 9 — Разные функции

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