sql >> Databasteknik >  >> RDS >> Database

Utforska modulens API:er i Java 9

Java 9 inkorporerade API:et i en samling moduler. Därför är modularitet det centrala temat; detta påverkade programdesignen från toppnivån. Program kan byggas modulärt redan från början. Det är ingen överraskning att det kommer att finnas API:er för att specifikt hantera programmeringselementet som kallas en modul . API:erna tillhandahåller ett sätt att komma åt moduler programmatiskt. Dessa API:er är ganska praktiska för att få specifik information om modulerna eller för att läsa eller manipulera dem. Den här artikeln utforskar klasserna Module APIs och några av metoderna, med exempel som ger dig en uppfattning om deras övergripande funktionalitet.

En översikt

Java 9 tillhandahåller en uppsättning klasser och gränssnitt för att hantera modulen programmatiskt. Dessa API:er är särskilt användbara för:

  • Läser, laddar och söker efter moduler
  • Läsa och manipulera modulbeskrivningar

Listan över API:er omfattas huvudsakligen av paket:java.lang och java.lang.module . Även om java.lang.module Paketet består av de flesta klasser och gränssnitt för att hantera modulbeskrivningar, java.lang paketet innehåller klasser Modul , ModuleLayer , och ett undantag, LayerInstantiationException . Bland dessa tre är modulen klass är av primär betydelse eftersom en instans av denna klass tillhandahåller alla metoder som är kopplade till läsning, laddning och sökning av moduler. Den viktigaste klassen i java.lang.module paketet är ModuleDescriptor . Den här klassen tillhandahåller de nödvändiga metoderna för att hantera modulbeskrivningar.

Modules API

Enligt Java API Documentation representerar modulklassen både namngivna och icke namngivna körtidsmoduler. Namngivna moduler har ett namn och konstrueras av Java Virtual Machine när en graf över moduler definieras till Java Virtual Machine för att skapa ett modullager. En icke namngiven modul har inget namn. Det finns en namnlös modul för varje ClassLoader , erhålls genom att anropa dess getUnamedModule metod. Alla typer som inte finns i en namngiven modul är medlemmar i deras definierande klassladdares namnlösa modul.

Det är enkelt att ta reda på modulen för en klass som den tillhör. Till exempel, om vi vill ta reda på modulen för en klass, säg ArrayList , från Collection API eller, säg, Applikation från JavaFX kan vi göra det på följande sätt.

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

Eller, i ett enda uttalande, enligt följande:

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

Detta skriver ut modulnamnet för klassen, till exempel java.base , för Arraylist och javafx.graphics för applikation . Eftersom en modul antingen kan namnges eller namnlösas, kan vi ta reda på det genom att anropa isNamed() metod. Den här metoden returnerar true om modulen är namngiven eller false om det är en namnlös modul. Här är ett exempel på icke namngivna moduler.

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

Utdata:

unnamed module @4c75cab9
null
null is Unnamed Module
null

Och för namngivna moduler kan vi skriva som följer:

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

Utdata:

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

Ett ModuleLayer innehåller endast namngivna moduler. Vi kan anropa getLayer metod för att få information om lagret den innehåller i modulen. Om den returnerar null betyder det att modulen inte är i ett lager, eller så är det en namnlös modul. Om vi ​​vill få en lista över tillgängliga paket i en modul kan vi anropa getPackages metod. getClassLoader metod returnerar modulklassladdaren. Här är ett exempel för att illustrera metoderna som beskrivs ovan.

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

Utdata:

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

Modulbeskrivning

Enligt Java 9 API Documentation, "En modulbeskrivning beskriver en namngiven modul och definierar metoder för att erhålla var och en av dess komponenter." Modulbeskrivningen för en namngiven modul i den virtuella Java-maskinen erhålls genom att anropa modulen s getDescriptor metod. Modulbeskrivningar kan också skapas genom att använda ModuleDescriptor.Builder klass eller genom att läsa den binära formen av en moduldeklaration (module-info.class ) med hjälp av läs metoder definierade i denna klass.

Därför brukar ModuleDescriptor instans representerar moduldefinitionen som finns i binär form av modulbeskrivningsfilen, kallad module-info.class . Förutom att läsa och manipulera moduldefinitioner kan vi använda ModuleDescriptor.Builder klass för att beskriva modulen vid körning.

En modulbeskrivning beskriver tre typer av moduler, till exempel normala, öppna och automatiska moduler.

En normal och en öppen modul beskriver uttryckligen de tjänster de tillhandahåller eller använder, beroenden, exporterade paket och andra komponenter. Huvudskillnaden mellan en normal modul och en öppen modul är att Normala moduler kan öppna specifika paket. Modulbeskrivningen för en öppen modul deklarerar inga öppna paket (dess öppnar metod returnerar en tom uppsättning), men när den instansieras i den virtuella Java-maskinen, behandlas den som om alla paket är öppna.

Den automatiska modulen deklarerar dock inga exporterade, öppna paket eller beroenden förutom implicit deklaration av java.base modul. När en automatisk modul instansieras i den virtuella Java-maskinen läser den alla namnlösa moduler och behandlas som om alla paket är exporterade och öppna.

getDescriptor metod för modulen klass returnerar en instans av ModuleDescriptor klass. ModuleDescriptor klass innehåller statiska kapslade klasser vars instans representerar direktivsatsen i moduldeklarationsfilen. Klassen innehåller dock inte användningar uttalande som vanligtvis kan representeras av en tjänsteinstans String . Här är de andra fyra:

  • ModuleDescriptor.Requires
  • ModuleDescriptor.Öppnar
  • ModuleDescriptor.Provides
  • ModuleDescriptor.Exports

Ett snabbt exempel

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

Utdata:

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]

Den binära modulbeskrivningsfilen, kallad module-info.class , kan läsas direkt på följande sätt för att skapa en instans av ModuleDescriptor klass:

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

Det finns fyra versioner av den överbelastade statiska läsningen metod definierad i ModuleDescriptor klass. De används för att läsa den binära formen av modulbeskrivningen från en ingångsström eller en bytebuffert. Här är utdraget från Java 9 API-dokumentation.

  • läs(InputStream in) :Läser den binära formen av en moduldeklaration från en indataström som en modulbeskrivning.
  • läs(InputStream in, Supplier > packageFinder) :Läser den binära formen av en moduldeklaration från en indataström som en modulbeskrivning.
  • läs(ByteBuffer bb) :Läser den binära formen av en moduldeklaration från en bytebuffert som en modulbeskrivning.
  • läs(ByteBuffer bb, leverantör > packageFinder) :Läser den binära formen av en moduldeklaration från en bytebuffert som en modulbeskrivning.

De uppsatta paketen av packageFinder inkludera alla paket som modulen exporterar, öppnar, tillhandahållna tjänster och paketet för huvudklassen som inte är kodade av deskriptorn som tillhandahålls i ingångsströmmen eller bytebufferten.

Slutsats

Förutom att läsa grundläggande information om modulen, är Modul klass tillhandahåller några nyckelmetoder för att fråga om modulens status – oavsett om den ska läsas, öppnas, exporteras och så vidare. API:et tillhandahåller även metoder som addOpens , addExport , addUses och addReads för att lägga till öppna och exportera användningsområden och läsa uttalanden till moduldeskriptorn programmatiskt. I ett nötskal ger Module API många andra metoder för att specifikt hantera moduler programmatiskt. Här har vi precis skrapat på ytan för att ge en första uppfattning om vad det handlar om.


  1. Analysera PostgreSQL-tabellstatistik

  2. EFTER LOGON(Oracle) trigger i PostgreSQL med tillägg – login_hook

  3. Hur skapar och frågar jag länkade databasservrar i SQL Server?

  4. Välj olåst rad i Postgresql