sql >> Database teknologi >  >> RDS >> Database

Udforskning af modul-API'erne i Java 9

Java 9 inkorporerede API'et i en samling af moduler. Derfor er modularitet det centrale tema; dette påvirkede programdesignet fra det øverste niveau. Programmer kan bygges modulært lige fra starten. Det er ingen overraskelse, at der vil være API'er til specifikt at beskæftige sig med programmeringselementet kaldet et modul . API'erne giver mulighed for at få adgang til moduler programmatisk. Disse API'er er ret praktiske til at få specifik information om modulerne eller til at læse eller manipulere dem. Denne artikel udforsker Modul APIs klasserne og nogle af metoderne med eksempler for at give dig en idé om deres overordnede funktionalitet.

En oversigt

Java 9 giver et sæt klasser og grænseflader til at håndtere modulet programmatisk. Disse API'er er særligt nyttige til:

  • Læsning, indlæsning og søgning af moduler
  • Læsning og manipulering af modulbeskrivelser

Listen over API'er er primært omfattet af pakker:java.lang og java.lang.module . Selvom java.lang.modulet pakken består af de fleste klasser og grænseflader til at håndtere modulbeskrivelser, java.lang pakken indeholder klasser Modul , ModuleLayer , og en undtagelse, LayerInstantiationException . Blandt disse tre er modulet klasse er af primær betydning, fordi en forekomst af denne klasse giver alle de metoder, der er forbundet med læsning, indlæsning og søgning af moduler. Den vigtigste klasse i java.lang.modulet pakken er ModuleDescriptor . Denne klasse giver de nødvendige metoder til at håndtere modulbeskrivelser.

Modules API

Ifølge Java API Documentation repræsenterer modulklassen både navngivne og unavngivne runtime-moduler. Navngivne moduler har et navn og er konstrueret af Java Virtual Machine, når en graf over moduler defineres til Java Virtual Machine for at skabe et modullag. Et unavngivet modul har ikke et navn. Der er et unavngivet modul for hver ClassLoader , opnået ved at kalde dets getUnamedModule metode. Alle typer, der ikke er i et navngivet modul, er medlemmer af deres definerende klasseindlæsers unavngivne modul.

Det er nemt at finde ud af modulet i en klasse, som det tilhører. For eksempel, hvis vi ønsker at finde ud af modulet i en klasse, siger ArrayList , fra Collection API eller f.eks. Applikation fra JavaFX, kan vi gøre det på følgende måde.

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

Eller i en enkelt erklæring som følger:

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

Dette udskriver modulnavnet på klassen, såsom java.base , for Arraylist , og javafx.graphics til ansøgning . Fordi et modul enten kan være navngivet eller unavngivet, kan vi finde ud af det ved at kalde isNamed() metode. Denne metode returnerer true hvis modulet er navngivet eller false hvis det er et unavngivet modul. Her er et eksempel på unavngivne 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());
   }
}

Output:

unnamed module @4c75cab9
null
null is Unnamed Module
null

Og for navngivne moduler kan vi skrive som følger:

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

Output:

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

Et ModuleLayer indeholder kun navngivne moduler. Vi kan kalde getLayer metode til at få information om det lag, det indeholder i modulet. Hvis det returnerer null, betyder det, at modulet ikke er i et lag, eller det er et unavngivet modul. Hvis vi ønsker at få en liste over tilgængelige pakker i et modul, kan vi kalde getPackages metode. getClassLoader metoden returnerer modulklasseindlæseren. Her er et eksempel for at illustrere de ovenfor beskrevne metoder.

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

Output:

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

Modulbeskrivelse

Ifølge Java 9 API-dokumentation, "En modulbeskrivelse beskriver et navngivet modul og definerer metoder til at opnå hver af dets komponenter." Modulbeskrivelsen for et navngivet modul i den virtuelle Java-maskine fås ved at kalde modulet 's getDescriptor metode. Modulbeskrivelser kan også oprettes ved at bruge ModuleDescriptor.Builder klasse eller ved at læse den binære form af en modulerklæring (module-info.class ) ved hjælp af read metoder defineret i denne klasse.

Derfor typisk ModuleDescriptor instans repræsenterer moduldefinitionen fundet i den binære form af modulbeskrivelsesfilen, kaldet module-info.class . Udover at læse og manipulere moduldefinitionen kan vi bruge ModuleDescriptor.Builder klasse for at beskrive modulet ved kørsel.

En modulbeskrivelse beskriver tre typer moduler, såsom normale, åbne og automatiske moduler.

Et normalt og et åbent modul beskriver eksplicit de tjenester, de leverer eller bruger, afhængigheder, eksporterede pakker og andre komponenter. Den største forskel mellem et normalt modul og et åbent modul er, at Normale moduler kan åbne specifikke pakker. Modulbeskrivelsen for et åbent modul erklærer ingen åbne pakker (dets åbner metoden returnerer et tomt sæt), men når den instansieres i den virtuelle Java-maskine, behandles den, som om alle pakker er åbne.

Det automatiske modul erklærer dog ingen eksporterede, åbne pakker eller afhængigheder undtagen implicit erklæring af java.base modul. Når et automatisk modul instantieres i den virtuelle Java-maskine, læser det hvert unavngivne modul og behandles, som om alle pakker er eksporteret og åbne.

getDescriptor metoden for modulet klasse returnerer en forekomst af ModuleDescriptor klasse. ModuleDescriptor klasse indeholder statiske indlejrede klasser, hvis instans repræsenterer direktivsætningen i modulerklæringsfilen. Klassen indeholder dog ikke brug sætning, som typisk kan repræsenteres af en serviceinstans String . Her er de fire andre:

  • ModuleDescriptor.Requires
  • ModuleDescriptor.Åbner
  • ModuleDescriptor.Provides
  • ModuleDescriptor.Exports

Et hurtigt eksempel

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

Output:

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]

Modulbeskrivelsens binære fil, kaldet module-info.class , kan læses direkte på følgende måde for at oprette en forekomst af ModuleDescriptor klasse:

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

Der er fire versioner af den overbelastede statiske læsning metode defineret i ModuleDescriptor klasse. De bruges til at læse den binære form af modulbeskrivelsen fra en inputstrøm eller en bytebuffer. Her er uddraget fra Java 9 API-dokumentation.

  • læs(InputStream in) :Læser den binære form af en modulerklæring fra en inputstrøm som en modulbeskrivelse.
  • læs(InputStream in, Supplier > packageFinder) :Læser den binære form af en modulerklæring fra en inputstrøm som en modulbeskrivelse.
  • læs(ByteBuffer bb) :Læser den binære form af en modulerklæring fra en bytebuffer som en modulbeskrivelse.
  • læs(ByteBuffer bb, Leverandør > packageFinder) :Læser den binære form af en modulerklæring fra en bytebuffer som en modulbeskrivelse.

De indstillede pakker af packageFinder inkludere alle de pakker, som modulet eksporterer, åbner, leverede tjenester og pakken af ​​hovedklassen, som ikke er kodet af deskriptoren, der leveres i inputstrømmen eller bytebufferen.

Konklusion

Udover at læse grundlæggende information om modulet, er modulet klasse giver nogle nøglemetoder til at forespørge om modulets status – uanset om den skal læses, åbnes, eksporteres og så videre. API'en tilbyder også metoder såsom addOpens , addExport , addUses , og addReads at tilføje åbne og eksportere anvendelser og læse sætninger til modulbeskrivelsen programmatisk. I en nøddeskal giver Module API mange andre metoder til specifikt at håndtere moduler programmatisk. Her har vi lige ridset overfladen for at give en indledende idé om, hvad det handler om.


  1. psycopg2 hvordan håndtere TypeError:ikke alle argumenter konverteres under strengformatering

  2. Android sqlite db.query fører til CursorIndexOutOfBoundsException

  3. Er der en MySQL-indstilling/-funktion til at spore historikken for ændringer i poster?

  4. Sådan genopbygger du en inkonsekvent PostgreSQL-slave