Database
 sql >> база данни >  >> RDS >> Database

Изследване на API на модулите в Java 9

Java 9 включва API в колекция от модули. Следователно модулността е централната тема; това повлия на дизайна на програмата от най-високо ниво. Програмите могат да бъдат изградени модулно от самото начало. Не е изненада, че ще има API, които да се справят конкретно с програмния елемент, наречен модул . API осигуряват начин за програмен достъп до модули. Тези API са доста удобни, за да получите конкретна информация за модулите или да ги четете или манипулирате. Тази статия разглежда класовете на API на модулите и някои от методите, с примери, които да ви дадат представа за цялостната им функционалност.

Общ преглед

Java 9 предоставя набор от класове и интерфейси за програмно справяне с модула. Тези API са особено полезни за:

  • Четене, зареждане и търсене на модули
  • Четене и манипулиране на дескриптори на модули

Списъкът с API е обхванат главно в пакети:java.lang и java.lang.module . Въпреки че java.lang.module пакетът се състои от повечето класове и интерфейси за работа с дескриптори на модули, java.lang пакет съдържа класове Module , ModuleLayer и изключение, LayerInstantiationException . Сред тези три, Модул class е от първостепенно значение, тъй като екземпляр на този клас предоставя всички методи, свързани с модулите за четене, зареждане и търсене. Най-важният клас в java.lang.module пакетът е ModuleDescriptor . Този клас предоставя необходимите методи за работа с дескриптори на модули.

API за модули

Съгласно документацията на Java API, класът модул представлява както наименувани, така и неименувани модули по време на изпълнение. Именуваните модули имат име и се изграждат от виртуалната машина на Java, когато към виртуалната машина на Java се дефинира графика от модули за създаване на модулен слой. Модул без име няма име. За всеки ClassLoader има модул без име , получен чрез извикване на неговия getUnnamedModule метод. Всички типове, които не са в наименуван модул, са членове на неименувания модул на дефиниращия им зареждащ клас.

Лесно е да разберете модула на клас, към който принадлежи. Например, ако искаме да разберем модула на клас, да речем, ArrayList , от API за колекция или, да речем, Приложение от JavaFX, можем да го направим по следния начин.

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

Или в едно изявление, както следва:

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

Това отпечатва името на модула на класа, като java.base , за Arraylist и javafx.graphics за Приложение . Тъй като модулът може да бъде с име или без име, можем да разберем, като извикаме isNamed() метод. Този метод връща true ако модулът е именуван или false ако е модул без име. Ето пример за модули без име.

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

Изход:

unnamed module @4c75cab9
null
null is Unnamed Module
null

А за наименуваните модули можем да напишем както следва:

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

Изход:

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

ModuleLayer съдържа само именувани модули. Можем да извикаме getLayer метод за получаване на информацията за слоя, който съдържа в модула. Ако върне null, това означава, че модулът не е в слой или е модул без име. Ако искаме да получим списък с пакети, налични в модул, можем да извикаме getPackages метод. getClassLoader метод връща модула за зареждане на класове. Ето пример за илюстриране на методите, описани по-горе.

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

Изход:

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

Описание на модула

Съгласно Документацията на API на Java 9 „Дескрипторът на модул описва наименуван модул и дефинира методи за получаване на всеки от неговите компоненти.“ Дескрипторът на модула за наименуван модул във виртуалната машина на Java се получава чрез извикване на Module getDescriptor метод. Дескрипторите на модули също могат да бъдат създадени с помощта на ModuleDescriptor.Builder клас или чрез четене на двоичната форма на декларация на модул (module-info.class ) с помощта на четене методи, дефинирани в този клас.

Следователно, обикновено ModuleDescriptor екземпляр представлява дефиницията на модула, намерена в двоичната форма на файла с дескриптор на модула, наречен module-info.class . Освен да четем и манипулираме дефиницията на модула, можем да използваме ModuleDescriptor.Builder клас за описание на модула по време на изпълнение.

Дескрипторът на модула описва три типа модули, като нормални, отворени и автоматични модули.

Нормален и отворен модул изрично описват услугите, които предоставят или използват, зависимостите, експортираните пакети и други компоненти. Основната разлика между нормален модул и отворен модул е, че Нормалните модули могат да отварят конкретни пакети. Дескрипторът на модула за отворен модул не декларира никакви отворени пакети (неговите отваря метод връща празен набор), но когато се инстанцира във виртуалната машина на Java, той се третира така, сякаш всички пакети са отворени.

Автоматичният модул обаче не декларира никакви експортирани, отворени пакети или зависимости освен имплицитната декларация на java.base модул. Когато автоматичен модул се инстанцира във виртуалната машина на Java, той чете всеки неименуван модул и се третира така, сякаш всички пакети са експортирани и отворени.

getDescriptor метод на модула клас връща екземпляр на ModuleDescriptor клас. Descriptor на модула клас съдържа статични вложени класове, чийто екземпляр представлява оператора на директивата във файла с декларация на модула. Класът обаче не съдържа употреби оператор, който обикновено може да бъде представен от екземпляр на услуга String . Ето другите четири:

  • ModuleDescriptor.Requires
  • ModuleDescriptor.Opens
  • ModuleDescriptor.Предоставя
  • ModuleDescriptor.Exports

Бърз пример

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

Изход:

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]

Двоичен файл с дескриптор на модула, наречен module-info.class , може да бъде прочетено директно по следния начин, за да създадете екземпляр на ModuleDescriptor клас:

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

Има четири версии на претовареното статично четене метод, дефиниран в ModuleDescriptor клас. Те се използват за четене на двоичната форма на описанието на модула от входен поток или байтов буфер. Ето извличането от документацията на Java 9 API.

  • четене (InputStream in) :Чете двоичната форма на декларация на модул от входен поток като дескриптор на модул.
  • read(InputStream in, Supplier > packageFinder) :Чете двоичната форма на декларация на модул от входен поток като дескриптор на модул.
  • четене(ByteBuffer bb) :Чете двоичната форма на декларация на модул от байтов буфер като дескриптор на модул.
  • read(ByteBuffer bb, Supplier > packageFinder) :Чете двоичната форма на декларация на модул от байтов буфер като дескриптор на модул.

Зададените пакети от packageFinder включват всички пакети, които модулът експортира, отваря, предоставяните услуги и пакета от основния клас, които не са кодирани от дескриптора, предоставен във входния поток или байтов буфер.

Заключение

Освен четене на основна информация за модула, Модул class предоставя някои ключови методи за запитване за състоянието на модула – дали той да бъде прочетен, отворен, експортиран и т.н. API също така предоставя методи като addOpens , addExport , addUses и addReads за добавяне на отворени и експортирани изрази за използване и четене към дескриптора на модулите програмно. Накратко, API на модулите предоставя много други методи за специално справяне с модулите програмно. Тук току-що надраскахме повърхността, за да дадем първоначална представа за какво става въпрос.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Разширени събития за SSAS

  2. За последен път, НЕ, не можете да се доверите на IDENT_CURRENT()

  3. Заключване и производителност

  4. Планиране на дисково пространство за бази данни

  5. Свържете ODBC приложения на Windows към QuickBooks Online