Database
 sql >> Baza danych >  >> RDS >> Database

Eksploracja interfejsów API modułów w Javie 9

Java 9 włączyła API do kolekcji modułów. Dlatego centralnym tematem jest modułowość; wpłynęło to na projekt programu z najwyższego poziomu. Programy mogą być od początku budowane modułowo. Nie jest niespodzianką, że pojawią się interfejsy API zajmujące się konkretnie elementem programowania zwanym modułem . Interfejsy API zapewniają sposób programowego dostępu do modułów. Te interfejsy API są bardzo przydatne, aby uzyskać szczegółowe informacje o modułach lub je odczytać lub manipulować. W tym artykule omówiono klasy interfejsów API modułu i niektóre metody, wraz z przykładami, aby dać wyobrażenie o ich ogólnej funkcjonalności.

Przegląd

Java 9 zapewnia zestaw klas i interfejsów do programowego radzenia sobie z modułem. Te interfejsy API są szczególnie przydatne w przypadku:

  • Czytanie, ładowanie i wyszukiwanie modułów
  • Odczytywanie i manipulowanie deskryptorami modułów

Lista API jest zawarta głównie w pakietach:java.lang i java.lang.module . Chociaż java.lang.module pakiet składa się z większości klas i interfejsów do obsługi deskryptorów modułów, java.lang pakiet zawiera klasy Moduł , ModuleLayer i wyjątek LayerInstantiationException . Wśród tych trzech Moduł Klasa ma pierwszorzędne znaczenie, ponieważ instancja tej klasy udostępnia wszystkie metody związane z odczytywaniem, ładowaniem i wyszukiwaniem modułów. Najważniejsza klasa w java.lang.module pakiet to ModuleDescriptor . Ta klasa zapewnia niezbędne metody do obsługi deskryptorów modułów.

Moduły API

Zgodnie z dokumentacją Java API, klasa modułu reprezentuje zarówno nazwane, jak i nienazwane moduły wykonawcze. Nazwane moduły mają nazwę i są konstruowane przez wirtualną maszynę Java, gdy graf modułów jest zdefiniowany w wirtualnej maszynie Java w celu utworzenia warstwy modułów. Moduł bez nazwy nie ma nazwy. Dla każdego ClassLoader istnieje nienazwany moduł , uzyskany przez wywołanie jego getUnnamedModule metoda. Wszystkie typy, które nie znajdują się w nazwanym module, są członkami nienazwanego modułu definiującego moduł ładujący klasy.

Łatwo jest znaleźć moduł klasy, do której należy. Na przykład, jeśli chcemy poznać moduł klasy, powiedzmy ArrayList , z interfejsu Collection API lub powiedzmy Aplikacji z JavaFX, możemy to zrobić w następujący sposób.

Class<ArrayList> c= ArrayList.class;
Module mod=c.getModule();
System.out.println(mod.getName());

Lub w jednym oświadczeniu w następujący sposób:

System.out.println(Application.class
   .getModule().getName());

Spowoduje to wypisanie nazwy modułu klasy, na przykład java.base , dla Lista tablic i javafx.graphics dla zgłoszenia . Ponieważ moduł może być nazwany lub nienazwany, możemy to sprawdzić, wywołując isNamed() metoda. Ta metoda zwraca prawdę jeśli moduł ma nazwę lub fałsz jeśli jest to moduł bez nazwy. Oto przykład nienazwanych modułów.

package org.mano.java9.examples;
public class Main {
   public static void main(String[] args) {
      Class<Main> c= Main.class;
      Module mod=c.getModule();
      System.out.println(mod);
      System.out.println(mod.getName());
      System.out.println(mod.getName()+" is "
         +(mod.isNamed()?
         "Named Module":"Unnamed Module"));
      System.out.println(mod.getDescriptor());
   }
}

Wyjście:

unnamed module @4c75cab9
null
null is Unnamed Module
null

A dla nazwanych modułów możemy napisać następująco:

package org.mano.java9.examples;
import java.util.ArrayList;
public class Main {
   public static void main(String[] args) {
      Class<ArrayList> c= ArrayList.class;
      Module mod=c.getModule();<
      System.out.println(mod);
      System.out.println(mod.getName());
      System.out.println(mod.getName()+" is "
         +(mod.isNamed()?
         "Named Module":"Unnamed Module"));
      System.out.println(mod.getDescriptor());
   }
}

Wyjście:

module java.base
java.base
java.base is Named Module
module { name: [email protected], uses:
   [java.nio.file.spi.FileTypeDetector, ...}

ModuleLayer zawiera tylko nazwane moduły. Możemy wywołać getLayer metody, aby uzyskać informacje o warstwie, którą zawiera w module. Jeśli zwraca null, oznacza to, że moduł nie znajduje się w warstwie lub jest modułem nienazwanym. Jeśli chcemy uzyskać listę pakietów dostępnych w module, możemy wywołać getPackages metoda. getClassLoader Metoda zwraca moduł ładujący klasy. Oto przykład ilustrujący metody opisane powyżej.

package org.app.module1;
import javafx.application.Application;
import java.util.Set;
public class Main {
   public static void main(String[] args) {
      Class<Application> c = Application.class;
      Module mod = c.getModule();
      System.out.println("Name :" 
         + mod.getName());
      System.out.println(mod.getName() + " is " 
         + (mod.isNamed() ? "Named Module" :
         "Unnamed Module"));
      System.out.println("Layer :" + mod.getLayer());
      System.out.println("ClassLoader :"
         + mod.getClassLoader());
      System.out.println("List of
         Packagesn.....................");
      Set<String> set = mod.getPackages();
      int i=1;
      for (String s : set) {
         System.out.println(i+++") "+s);
      }
   }
}

Wyjście:

Name :javafx.graphics
javafx.graphics is Named Module
Layer :jdk.compiler, java.compiler, jdk.management.jfr,
   jdk.scripting.nashorn, ...
ClassLoader :jdk.internal.loader.ClassLoaders
   [email protected]
....................
List of Packages
.....................
1) com.sun.javafx.stage
2) com.sun.scenario.effect.impl.prism.ps
3) javafx.print
...
107) com.sun.prism.j2d
108) javafx.scene.image

Opis modułu

Według dokumentacji Java 9 API „Deskryptor modułu opisuje nazwany moduł i definiuje metody uzyskiwania każdego z jego komponentów”. Deskryptor modułu dla nazwanego modułu w wirtualnej maszynie Java jest uzyskiwany przez wywołanie Modułu getDescriptor metoda. Deskryptory modułów można również tworzyć za pomocą ModuleDescriptor.Builder class lub czytając binarną formę deklaracji modułu (module-info.class ) za pomocą odczytu metody zdefiniowane w tej klasie.

Dlatego zazwyczaj ModuleDescriptor instancja reprezentuje definicję modułu znalezioną w postaci binarnej pliku deskryptora modułu o nazwie module-info.class . Oprócz czytania i manipulowania definicją modułu, możemy użyć ModuleDescriptor.Builder klasę opisującą moduł w czasie wykonywania.

Deskryptor modułu opisuje trzy typy modułów, takie jak moduły normalne, otwarte i automatyczne.

Zwykły i otwarty moduł wyraźnie opisują usługi, które dostarczają lub używają, zależności, eksportowane pakiety i inne komponenty. Główna różnica między zwykłym a otwartym modułem polega na tym, że Normalne moduły mogą otwierać określone pakiety. Deskryptor modułu dla otwartego modułu nie deklaruje żadnych otwartych pakietów (jego otwiera się Metoda zwraca pusty zestaw), ale po utworzeniu instancji w wirtualnej maszynie Java jest traktowana tak, jakby wszystkie pakiety były otwarte.

Moduł automatyczny nie deklaruje jednak żadnych eksportowanych, otwartych pakietów ani zależności, z wyjątkiem niejawnej deklaracji java.base moduł. Gdy automatyczny moduł jest tworzony na wirtualnej maszynie Java, odczytuje każdy nienazwany moduł i jest traktowany tak, jakby wszystkie pakiety zostały wyeksportowane i otwarte.

getDescriptor metoda Modułu klasa zwraca instancję ModuleDescriptor klasa. ModuleDescriptor class zawiera statyczne klasy zagnieżdżone, których instancja reprezentuje instrukcję dyrektywy w pliku deklaracji modułu. Klasa nie zawiera jednak zastosowań oświadczenie, które zazwyczaj może być reprezentowane przez instancję usługi String . Oto pozostałe cztery:

  • ModuleDescriptor.Requires
  • ModuleDescriptor.Opens
  • ModuleDescriptor.Provides
  • ModuleDescriptor.Exports

Szybki przykład

package org.mano.java9.examples;
import javax.sql.RowSet;
import java.lang.module.ModuleDescriptor;
import java.util.List;
public class Main {
   public static void main(String[] args) {
      System.out.println("Module Name: "
         + List.class.getModule().getName());
      show(List.class.getModule().getDescriptor());
      System.out.println("Module Name: "
         + RowSet.class.getModule().getName());
      show(RowSet.class.getModule().getDescriptor());
   }
   public static void show(ModuleDescriptor d) {
      System.out.println("Module
         Descriptionn-------------------------");
      System.out.println("Requires: " + d.requires());
      System.out.println("Exports: " + d.exports());
      System.out.println("Uses: " + d.uses());
      System.out.println("Provides: " + d.provides());
      System.out.println("Packages: " + d.packages());
   }
}

Wyjście:

Module Name: java.base
Module Description
-------------------------
Requires: []
Exports: [jdk.internal.org.objectweb.asm.signature to
   [jdk.scripting.nashorn], ...]
Uses: [java.util.spi.LocaleNameProvider,
   java.nio.file.spi.FileSystemProvider, ...]
Provides: [java.nio.file.spi.FileSystemProvider with
   [jdk.internal.jrtfs.JrtFileSystemProvider]]
Packages: [java.nio.file, jdk.internal.org.objectweb.asm
   .tree.analysis, com.sun.security.ntlm, ...]
Module Name: java.sql
Module Description
-------------------------
Requires: [mandated java.base, transitive java.logging,
   transitive java.xml]
Exports: [java.sql, javax.transaction.xa, javax.sql]
Uses: [java.sql.Driver]
Provides: []
Packages: [javax.sql, javax.transaction.xa, java.sql]

Plik binarny deskryptora modułu o nazwie module-info.class , można bezpośrednio odczytać w następujący sposób, aby utworzyć instancję ModuleDescriptor klasa:

try {
   ModuleDescriptor descriptor = ModuleDescriptor
      .read(new FileInputStream("module-info.class"));
} catch (IOException ex) { }

Istnieją cztery wersje przeciążonego odczytu statycznego metoda zdefiniowana w ModuleDescriptor klasa. Służą do odczytywania binarnej postaci opisu modułu ze strumienia wejściowego lub bufora bajtów. Oto wyciąg z dokumentacji API Java 9.

  • odczyt(InputStream w) :Czyta binarną formę deklaracji modułu ze strumienia wejściowego jako deskryptor modułu.
  • odczytaj (InputStream w, Dostawca > PackageFinder) :Czyta binarną formę deklaracji modułu ze strumienia wejściowego jako deskryptor modułu.
  • odczyt(ByteBuffer bb) :Czyta binarną formę deklaracji modułu z bufora bajtowego jako deskryptor modułu.
  • odczyt(ByteBuffer bb, Dostawca > packageFinder) :Czyta binarną formę deklaracji modułu z bufora bajtowego jako deskryptor modułu.

Zestaw pakietów przez packageFinder Uwzględnij wszystkie pakiety, które moduł eksportuje, otwiera, udostępnia usługi oraz pakiet głównej klasy, które nie są zakodowane przez deskryptor dostarczony w strumieniu wejściowym lub buforze bajtowym.

Wniosek

Oprócz zapoznania się z podstawowymi informacjami o module, Moduł class udostępnia kilka kluczowych metod do zapytania o stan modułu — czy jest on odczytany, otwarty, wyeksportowany i tak dalej. Interfejs API udostępnia również metody, takie jak addOpens , dodajEksport , addUżycia i dodajCzytaj programowe dodawanie otwartych i eksportowanych zastosowań oraz instrukcji odczytu do deskryptora modułów. Krótko mówiąc, interfejs API modułu zapewnia wiele innych metod do programowego radzenia sobie z modułami. Tutaj właśnie zarysowaliśmy powierzchnię, aby dać pierwsze wyobrażenie o tym, o co w tym wszystkim chodzi.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kompresja i jej wpływ na wydajność

  2. Wiele sposobów usuwania duplikatów z tabel SQL

  3. Zrozumienie wdrożenia Amazon Auroras Multi-AZ

  4. Porównaj cztery wiodące narzędzia IDE do baz danych

  5. Usługa migracji bazy danych AWS DMS