sql >> Databáze >  >> RDS >> Database

Prozkoumání modulových API v Javě 9

Java 9 začlenila API do kolekce modulů. Ústředním tématem je proto modularita; to ovlivnilo návrh programu z nejvyšší úrovně. Programy lze budovat modulárně hned od začátku. Není žádným překvapením, že budou existovat API, která se budou konkrétně zabývat programovacím prvkem zvaným modul . Rozhraní API poskytují způsob, jak přistupovat k modulům programově. Tato rozhraní API jsou docela užitečná pro získání konkrétních informací o modulech nebo pro čtení nebo manipulaci s nimi. Tento článek zkoumá třídy Module APIs a některé metody s příklady, které vám poskytnou představu o jejich celkové funkčnosti.

Přehled

Java 9 poskytuje sadu tříd a rozhraní, s nimiž lze modul programově pracovat. Tato rozhraní API jsou užitečná zejména pro:

  • Čtení, načítání a vyhledávání modulů
  • Čtení a manipulace s deskriptory modulů

Seznam API je zahrnut hlavně v balíčcích:java.lang a java.lang.module . Ačkoli modul java.lang.module balíček se skládá z většiny tříd a rozhraní pro práci s deskriptory modulů, java.lang balíček obsahuje třídy Modul , ModuleLayer a výjimka LayerInstantiationException . Mezi tyto tři patří modul třída má primární význam, protože instance této třídy poskytuje všechny metody spojené se čtením, načítáním a vyhledáváním modulů. Nejdůležitější třída v modulu java.lang.module balíček je ModuleDescriptor . Tato třída poskytuje nezbytné metody pro práci s deskriptory modulů.

Rozhraní API modulů

Podle dokumentace Java API představuje třída modulů pojmenované i nepojmenované moduly za běhu. Pojmenované moduly mají název a jsou konstruovány Java Virtual Machine, když je pro virtuální stroj Java definován graf modulů pro vytvoření vrstvy modulů. Nepojmenovaný modul nemá jméno. Pro každý ClassLoader existuje nepojmenovaný modul , získaného vyvoláním jeho getUnnamedModule metoda. Všechny typy, které nejsou v pojmenovaném modulu, jsou členy nepojmenovaného modulu zavaděče jejich definujících tříd.

Je jednoduché zjistit modul třídy, do které patří. Pokud například chceme zjistit modul třídy, řekněme ArrayList , z Collection API nebo řekněme Aplikace od JavaFX, můžeme tak učinit následujícím způsobem.

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

Nebo v jediném příkazu takto:

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

Tím se vytiskne název modulu třídy, například java.base , pro Seznam polí a javafx.graphics pro Aplikaci . Protože modul může být pojmenován nebo nepojmenovaný, můžeme to zjistit vyvoláním isNamed() metoda. Tato metoda vrací true pokud je modul pojmenován nebo false pokud se jedná o nepojmenovaný modul. Zde je příklad nepojmenovaných modulů.

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

Výstup:

unnamed module @4c75cab9
null
null is Unnamed Module
null

A pro pojmenované moduly můžeme psát takto:

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

Výstup:

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

Vrstva modulu obsahuje pouze pojmenované moduly. Můžeme vyvolat getLayer metoda k získání informací o vrstvě, kterou obsahuje v modulu. Pokud vrátí hodnotu null, znamená to, že modul není ve vrstvě nebo se jedná o nepojmenovaný modul. Pokud chceme získat seznam balíčků dostupných v modulu, můžeme vyvolat getPackages metoda. getClassLoader metoda vrací zavaděč třídy modulů. Zde je příklad pro ilustraci výše popsaných metod.

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

Výstup:

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

Popis modulu

Podle dokumentace API Java 9 „Deskriptor modulu popisuje pojmenovaný modul a definuje metody pro získání každé z jeho komponent.“ Deskriptor modulu pro pojmenovaný modul ve virtuálním počítači Java se získá vyvoláním Modulu 's getDescriptor metoda. Deskriptory modulu lze také vytvořit pomocí ModuleDescriptor.Builder class nebo čtením binární formy deklarace modulu (module-info.class ) pomocí čtení metody definované v této třídě.

Proto obvykle ModuleDescriptor instance představuje definici modulu nalezenou v binární podobě souboru deskriptoru modulu, nazvaného module-info.class . Kromě čtení a manipulace s definicí modulu můžeme použít ModuleDescriptor.Builder třídy pro popis modulu za běhu.

Popis modulu popisuje tři typy modulů, jako jsou normální, otevřené a automatické moduly.

Normální a otevřený modul explicitně popisuje služby, které poskytují nebo používají, závislosti, exportované balíčky a další komponenty. Hlavní rozdíl mezi normálním modulem a otevřeným modulem je ten, že Normální moduly mohou otevírat specifické balíčky. Popisovač modulu pro otevřený modul nedeklaruje žádné otevřené balíčky (jeho otevře metoda vrací prázdnou sadu), ale při vytvoření instance ve virtuálním stroji Java se s ní zachází, jako by byly všechny balíčky otevřené.

Automatický modul však nedeklaruje žádné exportované, otevřené balíčky nebo závislosti kromě implicitní deklarace java.base modul. Když je ve virtuálním stroji Java vytvořena instance automatického modulu, přečte každý nepojmenovaný modul a je s ním zacházeno, jako by byly exportovány a otevřeny všechny balíčky.

getDescriptor metoda Modulu class vrací instanci ModuleDescriptor třída. ModuleDescriptor class obsahuje statické vnořené třídy, jejichž instance představuje příkaz direktivy v souboru deklarace modulu. Třída však neobsahuje použití příkaz, který může být obvykle reprezentován instancí služby String . Zde jsou další čtyři:

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

Rychlý příklad

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

Výstup:

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]

Binární soubor deskriptoru modulu s názvem module-info.class , lze přímo číst následujícím způsobem a vytvořit tak instanci ModuleDescriptor třída:

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

Existují čtyři verze přetíženého statického čtení metoda definovaná v ModuleDescriptor třída. Používají se ke čtení binárního tvaru popisu modulu ze vstupního toku nebo bajtové vyrovnávací paměti. Zde je výňatek z dokumentace Java 9 API.

  • číst (InputStream in) :Čte binární formu deklarace modulu ze vstupního proudu jako deskriptor modulu.
  • číst (InputStream in, dodavatel > packageFinder) :Čte binární formu deklarace modulu ze vstupního proudu jako deskriptor modulu.
  • číst(ByteBuffer bb) :Čte binární formu deklarace modulu z bajtové vyrovnávací paměti jako deskriptor modulu.
  • read(ByteBuffer bb, Supplier > packageFinder) :Čte binární formu deklarace modulu z bajtové vyrovnávací paměti jako deskriptor modulu.

Nastavené balíčky pomocí packageFinder zahrnout všechny balíčky, které modul exportuje, otevře, poskytované služby a balíček hlavní třídy, které nejsou zakódovány deskriptorem dodaným ve vstupním proudu nebo bajtové vyrovnávací paměti.

Závěr

Kromě čtení základních informací o modulu, Modul class poskytuje některé klíčové metody, jak zjistit stav modulu – ať už je načten, otevřen, exportován a tak dále. Rozhraní API také poskytuje metody jako addOpens , addExport , addUses a addReads pro programové přidání otevřených a exportních použití a čtení do deskriptoru modulů. Stručně řečeno, modul API poskytuje mnoho dalších metod, jak konkrétně programově pracovat s moduly. Zde jsme jen poškrábali povrch, abychom získali první představu o tom, o co jde.


  1. Emulujte klauzuli MySQL LIMIT v Microsoft SQL Server 2000

  2. Proč bych v PHP neměl používat funkce mysql_*?

  3. Jak formátovat záporná čísla pomocí úhlových závorek v Oracle

  4. Kontingenční data v T-SQL