Java 9 - szybki przewodnik

JAVA 9 (aka jdk 1.9) to główne wydanie języka programowania JAVA. Jego pierwotna wersja została wydana 21 września 2017 r. Główne cele wydania Java 9 to:

  • Aby platforma JDK i Java Standard Edition była modułowa w tym sensie, że można ją dobrze sprowadzić do małych urządzeń komputerowych.

  • Poprawa ogólnego bezpieczeństwa implementacji JDK i Java.

  • Aby ułatwić proces budowania i utrzymywanie bibliotek kodu Java i dużych aplikacji dla platform JAVA SE i EE.

  • Zaprojektować i wdrożyć standardowy system modułowy dla platformy Java, który można łatwo zastosować zarówno na platformie, jak i JDK.

Nowe funkcje

Dodano ponad 90 ulepszeń do Java 8, najważniejsze z nich wymieniono poniżej -

  • Module - Nowy rodzaj komponentu Java wprowadzonego jako moduł, który jest nazwanym, samoopisującym się zbiorem kodu i danych.

  • REPL (JShell) - Do platformy Java dodano funkcję Read-Eval-Print Loop (REPL).

  • HTTP 2 Client - nowy interfejs API HTTPClient obsługujący gniazda sieciowe i strumienie HTTP 2 oraz funkcje wypychania serwera.

  • Improved JavaDocs- Obsługuje generowanie danych wyjściowych HTML5. Udostępnia pole wyszukiwania do wygenerowanej dokumentacji API.

  • Multirelease JAR - Ulepsza format JAR, dzięki czemu wiele wersji plików klas specyficznych dla wydania Java może współistnieć w jednym archiwum.

  • Collection Factory Methods - Nowe statyczne metody fabryki dla interfejsów List, Set i Map do tworzenia niezmiennych instancji tych kolekcji.

  • Private Interface Methods - Ulepszone interfejsy z prywatnymi i prywatnymi metodami statycznymi.

  • Process API Improvements - Ulepszone API do kontroli i zarządzania procesami systemu operacyjnego.

  • Stream API Improvements - Zwiększone bezpieczeństwo i niezawodność poprzez umożliwienie filtrowania przychodzących strumieni danych serializacji obiektów.

  • Try With Resources improvement - Teraz końcowe zmienne mogą być używane jako zasoby w instrukcji try-with-resources.

  • Enhanced @Deprecated Annotation - Zmodyfikowana adnotacja @Deprecated, aby zapewnić więcej informacji o stanie i zamierzonej dyspozycji interfejsu API.

  • Inner Class Diamond Operator - Zezwalaj na używanie operatora rombu z klasami anonimowymi, jeśli typ argumentu typu wywnioskowanego można oznaczyć.

  • Optional Class Improvements - Do klasy java.util.Optional dodano nowe przydatne metody.

  • Multiresolution Image API - Obsługuje hermetyzację zestawu obrazów o różnych rozdzielczościach w jednym obrazie wielorozdzielczym.

  • CompletableFuture API improvements - Mechanizmy asynchroniczne klasy CompletableFuture mogą wykonywać akcję po zakończeniu procesu za pomocą metody ProcessHandle.onExit.

  • Lightweight JSON - Lekki interfejs API wprowadzony do konsumowania i generowania dokumentów i strumieni danych za pośrednictwem json w java 9.

  • Reactive Streams API - Wprowadzono nowy interfejs API strumieni reaktywnych w Javie SE 9, aby wspierać programowanie reaktywne w Javie 9.

Konfiguracja środowiska lokalnego

Jeśli chcesz skonfigurować własne środowisko dla języka programowania Java, ta sekcja przeprowadzi Cię przez cały proces. Wykonaj poniższe kroki, aby skonfigurować środowisko Java.

Java SE jest dostępna do pobrania bezpłatnie. Aby pobrać, kliknij tutaj , pobierz wersję zgodną z Twoim systemem operacyjnym.

Postępuj zgodnie z instrukcjami, aby pobrać Javę i uruchomić .exeaby zainstalować Javę na swoim komputerze. Po zainstalowaniu Javy na komputerze należałoby ustawić zmienne środowiskowe, aby wskazywały na prawidłowe katalogi instalacyjne.

Konfigurowanie ścieżki dla systemu Windows 2000 / XP

Zakładając, że zainstalowałeś Javę w katalogu c: \ Program Files \ java \ jdk -

  • Kliknij prawym przyciskiem myszy „Mój komputer” i wybierz „Właściwości”.

  • Kliknij przycisk „Zmienne środowiskowe” na karcie „Zaawansowane”.

  • Teraz edytuj zmienną „Path” i dodaj na końcu ścieżkę do katalogu wykonywalnego Java. Na przykład, jeśli ścieżka jest obecnie ustawiona na C:\Windows\System32, edytuj ją w następujący sposób

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

Konfigurowanie ścieżki dla Windows 95/98 / ME

Zakładając, że zainstalowałeś Javę w katalogu c: \ Program Files \ java \ jdk -

  • Edytuj plik „C: \ autoexec.bat” i dodaj następujący wiersz na końcu -

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

Konfigurowanie ścieżki dla systemów Linux, UNIX, Solaris, FreeBSD

Zmienna środowiskowa PATH powinna być ustawiona tak, aby wskazywała, gdzie zostały zainstalowane pliki binarne Java. Zajrzyj do dokumentacji powłoki, jeśli masz z tym problem.

Na przykład, jeśli używasz basha jako powłoki, to dodasz następujący wiersz na końcu pliku .bashrc -

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

Popularne edytory Java

Do pisania programów w języku Java potrzebny jest edytor tekstu. Na rynku dostępne są jeszcze bardziej wyrafinowane środowiska IDE. Najpopularniejsze z nich zostały krótko opisane poniżej -

  • Notepad- Na komputerze z systemem Windows możesz użyć dowolnego prostego edytora tekstu, takiego jak Notatnik (zalecany w tym samouczku) lub WordPad. Notepad ++ to także darmowy edytor tekstu, który rozszerzył możliwości.

  • Netbeans - Jest to środowisko Java IDE o otwartym kodzie źródłowym i bezpłatne, które można pobrać z witryny https://www.netbeans.org/index.html.

  • Eclipse - Jest to również środowisko Java IDE opracowane przez społeczność Open Source Eclipse i można je pobrać z witryny https://www.eclipse.org/.

IDE lub zintegrowane środowisko programistyczne zapewnia wszystkie popularne narzędzia i udogodnienia pomocne w programowaniu, takie jak edytor kodu źródłowego, narzędzia do kompilacji i debuggery itp.

Java 9, nowy rodzaj komponentu programistycznego zwany modułem. Moduł to samoopisujący się zbiór kodu i danych, który ma nazwę, która go identyfikuje.

funkcje

Wraz z komponentem Moduły w Javie 9 dodano następujące ulepszenia -

  • Wprowadzono nową opcjonalną fazę, czas łącza. Ta faza jest pomiędzy czasem kompilacji a czasem wykonywania. Na tym etapie można zmontować i zoptymalizować zestaw modułów, tworząc niestandardowy obraz środowiska wykonawczego za pomocą narzędzia jlink.

  • javac, jlink i java mają dodatkowe opcje określania ścieżek modułów, które dodatkowo lokalizują definicje modułów.

  • Format JAR zaktualizowany jako modułowy JAR, który zawiera plik module-info.class w swoim katalogu głównym.

  • Wprowadzono format JMOD, format pakowania (podobny do JAR), który może zawierać kod natywny i pliki konfiguracyjne.

Tworzenie modułu

Postępując zgodnie z instrukcjami tworzenia modułu, powiedz com.tutorialspoint.greetings.

Krok 1

Utwórz folder C: \> JAVA \ src. Teraz utwórz folder com.tutorialspoint.greetings, który jest taki sam jak nazwa tworzonego modułu.

Krok 2

Utwórz folder module-info.java w folderze C: \> JAVA \ src \ com.tutorialspoint.greetings z następującym kodem.

module-info.java

module com.tutorialspoint.greetings { }

module-info.java to plik używany do tworzenia modułu. W tym kroku stworzyliśmy moduł o nazwie com.tutorialspoint.greetings. Zgodnie z konwencją ten plik powinien znajdować się w folderze, którego nazwa jest taka sama jak nazwa modułu.

Krok 3

Dodaj kod źródłowy w module. Utwórz folder Java9Tester.java w C: \> JAVA \ src \ com.tutorialspoint.greetings \ com \ tutorialspoint \ greetings z następującym kodem.

Java9Tester.java

package com.tutorialspoint.greetings;

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

Zgodnie z konwencją kod źródłowy modułu znajduje się w tym samym katalogu, który jest nazwą modułu.

Krok 4

Utwórz folder C: \> JAVA \ mods. Teraz utwórz folder com.tutorialspoint.greetings, który jest taki sam, jak nazwa utworzonego przez nas modułu. Teraz skompiluj moduł do katalogu mods.

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

Krok 5

Uruchommy moduł, aby zobaczyć wynik. Uruchom następujące polecenie.

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

Tutaj module-path podaje lokalizację modułu jako mods, a -m oznacza moduł główny.

Wynik

Wyświetli następujące dane wyjściowe na konsoli.

Hello World!

REPL to skrót od Read-Eval-Print Loop. Dzięki JShell java ma możliwość REPL. Korzystając z REPL, możemy kodować i testować logikę opartą na Javie bez kompilacji przy użyciu javac i bezpośrednio zobaczyć wynik obliczeń.

Uruchamianie JShell

Otwórz wiersz polecenia i wpisz jshell.

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

Przeglądanie poleceń JShell

Wpisz / help po uruchomieniu polecenia 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

Uruchomienie polecenia JShell

Wpisz / Import po uruchomieniu polecenia jshell i zobacz używane importy.

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>

Wykonywanie obliczeń w JShell.

Spróbuj uruchomić proste obliczenia w JShell.

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

Tworzenie i używanie funkcji w JShell

Utwórz funkcję doubled (), która pobierze wartość int i zwróci jej podwójną wartość.

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

Zamykanie JShell

Wpisz / wyjdź.

jshell> /exit
| Goodbye

Dokumentację Java można wygenerować za pomocą narzędzia javadoc. Obecnie generuje dokumentację w formacie html 4.0. W java 9 możemy wygenerować dokumentację w formacie html 5 używając opcji -html5 w argumentach wiersza poleceń.

Dokumentacja Java w starym stylu

Rozważ następujący kod w folderze C: / JAVA.

Tester.java

/**
 * @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");
   }
}

Teraz uruchom narzędzie javadoc z jdk 7, aby wygenerować dokumentację.

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...

Spowoduje to utworzenie strony dokumentacji Java w katalogu C: / JAVA, a zobaczysz następujące dane wyjściowe.

Nowa dokumentacja java z obsługą wyszukiwania i HTML5

Uruchom narzędzie javadoc z jdk 9 z flagą -html5, aby wygenerować nowy typ dokumentacji.

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...

Utworzy zaktualizowaną stronę dokumentacji java w katalogu D: / test i zobaczysz następujące dane wyjściowe.

W java 9 wprowadzono nową funkcję, w której format jar został ulepszony, aby mieć różne wersje klas java lub zasobów, które mogą być obsługiwane i używane zgodnie z platformą. W JAR plik MANIFEST.MF ma wpis Multi-Release: true w swojej sekcji głównej. Katalog META-INF zawiera również podkatalog wersji, którego podkatalogi (zaczynając od 9 w przypadku języka Java 9) przechowują klasy i pliki zasobów specyficzne dla wersji.

W tym przykładzie użyjemy pliku jar z wieloma wydaniami, aby mieć dwie wersje pliku Tester.java, jedną dla jdk 7 i jedną dla jdk 9, i uruchomimy go na różnych wersjach jdk.

Kroki

Step 1- Utwórz folder c: / test / java7 / com / tutorialspoint. Utwórz Test.java z następującą zawartością -

Tester.java

package com.tutorialspoint;

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

Step 2- Utwórz folder c: / test / java9 / com / tutorialspoint. Utwórz Test.java z następującą zawartością -

Tester.java

package com.tutorialspoint;

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

Skompiluj kody źródłowe.

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

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

Utwórz słoik z wieloma wersjami

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

Uruchom z JDK 7

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

Uruchom z JDK 9

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

W Javie 9 nowe metody fabryczne są dodawane do interfejsów List, Set i Map w celu tworzenia niezmiennych instancji. Te metody fabryczne są wygodnymi metodami fabrycznymi służącymi do tworzenia kolekcji w mniej szczegółowy i zwięzły sposób.

Stary sposób tworzenia kolekcji

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);
   }
}

Wynik

Wydrukuje następujący wynik.

[A, B, C]
[A, B, C]
{A=Apple, B=Boy, C=Cat}

Nowe metody

W Javie 9 do interfejsów List, Set i Map wraz z ich przeciążonymi odpowiednikami dodano następujące metody.

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)

Punkty, na które należy zwrócić uwagę

  • W przypadku interfejsów List i Set metoda of (...) jest przeciążona, aby mieć od 0 do 10 parametrów i jedną z parametrem var args.

  • W przypadku interfejsu Map metoda of (...) jest przeciążona i ma od 0 do 10 parametrów.

  • W przypadku więcej niż 10 parametrów interfejsu Map można zastosować metodę ofEntries (...) akceptującą parametr var args.

Nowy sposób tworzenia kolekcji

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);
   }
}

Wynik

Wydrukuje następujący wynik.

[A, B, C]
[A, B, C]
{A=Apple, B=Boy, C=Cat}
{A=Apple, B=Boy, C=Cat}

W wersjach starszych niż Java 8 interfejsy mogą mieć następujące typy zmiennych / metod.

  • Zmienne stałe
  • Metody abstrakcyjne

Nie możemy więc mieć implementacji metody w interfejsach, a dokładniej domyślnej implementacji przed Java 8. Zobacz przykład.

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();
}

Wynik

Zobaczysz następujące dane wyjściowe.

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

W powyższym przykładzie każda metoda dziennika ma swoją własną implementację. W przypadku interfejsów Java 8 mogą występować następujące typy zmiennych / metod.

  • Zmienne stałe
  • Metody abstrakcyjne
  • Metody domyślne
  • Metody statyczne

Miejmy domyślną implementację i metody statyczne w samym interfejsie za pomocą Java 8.

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");
   }
}

Wynik

Zobaczysz następujące dane wyjściowe.

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

W powyższym przykładzie znowu mamy powtórzenie. W przypadku interfejsów Java 9 mogą występować następujące typy zmiennych / metod.

  • Zmienne stałe
  • Metody abstrakcyjne
  • Metody domyślne
  • Metody statyczne
  • Metody prywatne
  • Prywatne metody statyczne

Miejmy prywatne metody i używajmy ich w Javie 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");
   }
}

Wynik

Zobaczysz następujące dane wyjściowe.

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

W Java 9 Process API, które jest odpowiedzialne za kontrolę i zarządzanie procesami systemu operacyjnego, zostało znacznie ulepszone. Klasa ProcessHandle zapewnia teraz natywny identyfikator procesu procesu, czas rozpoczęcia, skumulowany czas procesora, argumenty, polecenie, użytkownika, proces nadrzędny i potomków. Klasa ProcessHandle udostępnia również metodę sprawdzania żywotności procesów i niszczenia procesów. Posiada metodę onExit, klasa CompletableFuture może wykonywać akcję asynchronicznie po zakończeniu procesu.

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));
   } 
}

Wynik

Zobaczysz następujące dane wyjściowe.

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

Strumienie zostały wprowadzone w Javie, aby pomóc programistom w wykonywaniu zagregowanych operacji z sekwencji obiektów. W Javie 9 dodano kilka dodatkowych metod ulepszania strumieni.

takeWhile (Predicate Interface)

Składnia

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

Metoda takeWhile przyjmuje wszystkie wartości, dopóki predykat nie zwróci wartości false. Zwraca, w przypadku strumienia uporządkowanego, strumień składający się z najdłuższego prefiksu elementów pobranych z tego strumienia, pasujących do danego predykatu.

Przykład

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);		 
   } 
}

Wynik

Metoda takeWhile przyjmuje wszystkie wartości a, b i c, a gdy string jest pusty, przestaje wykonywać.

abc

dropWhile (interfejs predykatu)

Składnia

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

dropWhile odrzuca wszystkie wartości na początku, dopóki predykat nie zwróci true. W przypadku strumienia uporządkowanego zwraca strumień składający się z pozostałych elementów tego strumienia po odrzuceniu najdłuższego prefiksu elementów pasujących do danego predykatu.

Przykład

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);
   } 
}

Wynik

dropWhile odrzuca wartości a, b i c, a gdy łańcuch jest pusty, przyjmuje wszystkie wartości.

ef
ef

powtarzać

Składnia

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

iterate ma teraz predykat hasNext jako parametr, który zatrzymuje pętlę, gdy predykat hasNext zwróci wartość false.

Przykład

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);
   } 
}

Wynik

3
6
9

ofNullable

Składnia

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

ofNullable została wprowadzona, aby zapobiec NullPointerExceptions i uniknąć sprawdzania wartości null dla strumieni. Ta metoda zwraca sekwencyjny Stream zawierający pojedynczy element, jeśli nie ma wartości null, w przeciwnym razie zwraca pusty Stream.

Przykład

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);
   } 
}

Wynik

1
0

Instrukcja try-with-resources to instrukcja try z jednym lub większą liczbą należycie zadeklarowanych zasobów. Zasób to obiekt, który powinien zostać zamknięty, gdy nie jest już potrzebny. Instrukcja try-with-resources zapewnia, że ​​każdy zasób zostanie zamknięty po zakończeniu wymagania. Jako zasób można użyć dowolnego obiektu implementującego interfejs java.lang.AutoCloseable lub java.io.Closeable.

Przed wersją Java 9 zasoby należy zadeklarować przed instrukcją try lub wewnątrz instrukcji try, jak pokazano poniżej w podanym przykładzie. W tym przykładzie użyjemy BufferedReader jako zasobu do odczytu ciągu, a następnie BufferedReader zostanie zamknięty.

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 (BufferedReader br1 = br) {
         return br1.readLine();
      }
   }
}

Wynik

test

Tutaj musimy zadeklarować zasób br1 w instrukcji try, a następnie go użyć. W Javie9 nie musimy już deklarować br1 i kolejny program da ten sam wynik.

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();
      }
   }
}

Wynik

test

@Deprecated adnotation został wprowadzony w wersji java 5. Element programu z adnotacją @Deprecated oznacza, że ​​nie powinien być używany z żadnego z następujących powodów -

  • Jego użycie może prowadzić do błędów.
  • To może być niekompatybilne w przyszłych wersjach.
  • Może zostać usunięty w przyszłej wersji.
  • Lepsza i wydajniejsza alternatywa zastąpiła go.

Kompilator generuje ostrzeżenia za każdym razem, gdy używany jest przestarzały element. W Javie 9 dodano dwa nowe ulepszenia adnotacji @Deprecated.

  • forRemoval- Wskazuje, czy element z adnotacją ma zostać usunięty w przyszłej wersji. Wartość domyślna to false.

  • since- Zwraca wersję, w której element z adnotacją stał się przestarzały. Wartością domyślną jest pusty ciąg.

Przestarzałe od od

Poniższy przykład klasy logicznej javadoc w Javie 9 ilustruje użycie atrybutu since w adnotacji @Deprecated.

Klasa logiczna

Przestarzałe z forRemoval

Poniższy przykład klasy systemowej javadoc w Javie 9 ilustruje użycie atrybutu forRemoval w adnotacji @Deprecated.

Klasa systemu

Operator Diamond został wprowadzony w java 7, aby uczynić kod bardziej czytelnym, ale nie można go używać z klasami wewnętrznymi Anonymous. W java 9 może być również używany z klasą anonimową, aby uprościć kod i poprawić czytelność. Rozważ następujący kod przed wersją Java 9.

Tester.java

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();
}

Wynik

1
2
Test

W Javie 9 możemy użyć operatora <> z klasą anonimową, jak pokazano poniżej.

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();
}

Wynik

1
2
Test

Klasa opcjonalna została wprowadzona w Javie 8, aby uniknąć sprawdzania wartości null i problemów z wyjątkami NullPointerException. W Javie 9 dodano trzy nowe metody w celu poprawy jego funkcjonalności.

  • stream()
  • ifPresentOrElse()
  • or()

stream (), metoda

Składnia

public Stream<T> stream()

Jeśli wartość jest obecna, zwraca sekwencyjny Stream zawierający tylko tę wartość, w przeciwnym razie zwraca pusty Stream.

Przykład

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);
   }  
}

Wynik

[A, B]
[A, B]

ifPresentOrElse ()

Składnia

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

Jeśli wartość jest obecna, wykonuje daną akcję z wartością, w przeciwnym razie wykonuje daną akcję opartą na pustym miejscu.

Przykład

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."));
   }  
}

Wynik

Value: 1
Not Present.

lub () metoda

Składnia

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

Jeśli wartość jest obecna, zwraca opcjonalny opisujący wartość, w przeciwnym razie zwraca opcjonalny utworzony przez funkcję dostarczającą.

Przykład

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));  
   }  
}

Wynik

Value: Mahesh
Value: Not Present

W Javie 9 wprowadzono nowy interfejs API obrazów o wielu rozdzielczościach, który obsługuje wiele obrazów w różnych wariantach rozdzielczości. Ten interfejs API umożliwia użycie zestawu obrazów o różnej rozdzielczości jako pojedynczego obrazu o wielu rozdzielczościach. Poniżej przedstawiono główne operacje na obrazach o wielu rozdzielczościach.

  • Image getResolutionVariant(double destImageWidth, double destImageHeight) - Pobiera określony obraz, który jest najlepszym wariantem do reprezentowania tego logicznego obrazu we wskazanym rozmiarze.

  • List<Image> getResolutionVariants() - Pobiera czytelną listę wszystkich wariantów rozdzielczości.

Przykład

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));
   }  
}

Wynik

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]

Klasa CompletableFuture została wprowadzona w Javie 8, aby reprezentować przyszłość, którą można uzupełnić, ustawiając jej wartość i jednoznaczność. Może być używany jako java.util.concurrent.CompletionStage. Obsługuje zależne funkcje i działania, które zostały uruchomione po zakończeniu przyszłości. W java 9 CompletableFuture API zostało jeszcze bardziej ulepszone. Poniżej przedstawiono odpowiednie zmiany wprowadzone w interfejsie API.

  • Obsługa opóźnień i limitów czasu.
  • Ulepszona obsługa podklas.
  • Dodano nowe metody fabryczne.

Obsługa opóźnień i limitów czasu

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

Ta metoda uzupełnia CompletableFuture z podaną wartością, jeśli nie zostanie ukończona w inny sposób przed podanym limitem czasu.

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

Ta metoda wyjątkowo kończy to CompletableFuture z TimeoutException, jeśli nie zostanie ukończona w inny sposób przed podanym limitem czasu.

Ulepszona obsługa podklas

public Executor defaultExecutor()

Zwraca domyślny Executor używany dla metod asynchronicznych, które nie określają Executora. Ta metoda może zostać zastąpiona w podklasach, aby zwrócić Executor w celu zapewnienia co najmniej jednego niezależnego wątku.

public <U> CompletableFuture<U> newIncompleteFuture()

Zwraca nową niekompletną CompletableFuture typu, który ma zostać zwrócony przez metodę CompletionStage. Podklasy klasy CompletableFuture powinny przesłonić tę metodę, aby zwrócić wystąpienie tej samej klasy, co ta CompletableFuture. Domyślna implementacja zwraca wystąpienie klasy CompletableFuture.

Nowe metody fabryczne

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

Ta metoda fabryczna zwraca nową CompletableFuture, która została już zakończona z podaną wartością.

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

Ta metoda fabryczna zwraca nowy CompletionStage, który jest już zakończony z podaną wartością i obsługuje tylko metody obecne w interfejsie CompletionStage.

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

Ta metoda fabryczna zwraca nową CompletionStage, która została już wyjątkowo zakończona z danym wyjątkiem i obsługuje tylko metody obecne w interfejsie CompletionStage.

Oprócz wspomnianych funkcji, w Javie 9 wprowadzono znacznie więcej ulepszeń do platformy JDK. Niektóre z nich są wymienione poniżej.

  • Ulepszenia GC (Garbage Collector)
  • Stack-Walking API
  • Filtruj przychodzące dane serializacji
  • Wycofaj aplet API
  • Wskaż konkatenację ciągów
  • Ulepszone uchwyty metod
  • Interfejs API i usługa Java Platform Logging
  • Kompaktowe struny
  • Parser API dla Nashorn