[Java] Modul
      
      
        
        
        
        
Was ist ein Modul?
- Paket übergeordnetes Konzept
 
- Verfassung
 
- ** Pakete und zugehörige Ressourcen **
 
- Moduldefinitionsdatei, die ihre eigenen Konfigurationsinformationen definiert **
 
Traditionelle Verpackungsprobleme
Zugriffsrechte können nicht für jedes Paket festgelegt werden
- Für Pakete, die innerhalb der Bibliothek verwendet werden sollen, möchte ich den Zugriff von außerhalb der Bibliothek verhindern.
 
- Es gibt jedoch keine Möglichkeit, die ** öffentliche Klasse für den internen Gebrauch unsichtbar zu machen **
 
Die JAR-Datei kann keine Abhängigkeiten darstellen
- Mehrere Pakete werden als komprimierte Datei im JAR-Format kombiniert und als Bibliothek bereitgestellt.
 
- .Jar kann jedoch keine Abhängigkeiten zwischen Bibliotheken ausdrücken
 
- In der .jar ** Ich weiß nicht, welche Art von API von außen verwendet werden soll oder welche Bibliothek für den Betrieb benötigt wird **
 
Gelöst mit Modulen!
- ** Bündeln Sie bestimmte Bibliotheken und Frameworks in Gruppen **
 
- Die modulare Bibliothek ermöglicht eine feinere Verwaltung öffentlicher Klassen
 
- ** Öffentlich ** nur im aktuellen Modul
 
- ** Öffentlich ** nur für bestimmte Module
 
- ** Öffentlich für alle Module (wie zuvor) **
 
Modul grundlegend
- Beschreiben Sie die Moduldefinitionsdatei mit ** module-info.java ** direkt unter / sec
 
- ** Listen Sie Pakete auf, von denen das Modul abhängt, Paketinformationen, die nach außen gerichtet sind **
 
- Wenn Sie die erforderlichen Bibliotheken nicht in require deklarieren, ist "Der Typ java.net.http.HttpRequest ist nicht zugänglich"
 
module-info.java
//Modulname foo
//Java im Foo-Modul.net.brauche http
module foo {
  requires java.net.http;
  requires mylib;
  requires gson;
}
Standardbibliotheksmodul
- Die Standardbibliothek ist ebenfalls modularisiert
 
Grundmodul
- java.base
 
- Es ist mühsam, die Standardbibliotheken einzeln hinzuzufügen. ** Häufig verwendete Pakete werden im Modul java.base gruppiert. **
 
- Das Modul java.base wird implizit geladen, sodass keine explizite Deklaration erforderlich ist
 
- Es gibt auch ein ** java.se-Modul **, das die gesamte Java-Standardbibliothek definiert, aber auch unnötige Module lädt.
 
Übergangsabhängigkeit
- ** Übergang **: Wenn das geladene Modul von einem anderen Modul abhängig ist, wird auch das abhängige Ziel geladen.
 
- ** erfordert transitiv **, um Übergangsabhängigkeiten gut zu lösen
 
module-info.java
module java.se { 
  requires transitive java.compiler;
  requires transitive java.datatranfer;
  requires transitive java.desktop;
//Abkürzung
}
Paketfreigabe
- Wenn Sie Ihr Paket veröffentlichen möchten
 
- Es gibt Pakete (lib), die Sie nach außen veröffentlichen möchten, und Pakete, die Sie in der Bibliothek verwenden (intern).
 
- ** Nur in der Ausfuhrrichtlinie ** veröffentlichte Bibliotheken können extern veröffentlicht werden
 
module-info.java
module mylib { 
  exports mylib.lib;
}
//OK
import mylib.lib.MainLib;
//NG! interna;Paket ist unsichtbar
//import mylib.internal.Sublib;
public class ModuleClient {
  public static void main(String[] args) {
    var main = new MainLib();
    main.run();
  }
}
module foo {
  requires java.net.http;
  requires mylib;
  requires gson;
}
Paketfreigabe nur für bestimmte Module
- ** exportiert Paket in Modul **
 
- In den folgenden Fällen ist das lib-Paket nur für das foo-Modul verfügbar
 
- Mit 
, können mehrere Veröffentlichungsziele angegeben werden 
module-info.java
module mylib {
  exports mylib.lib to foo;
}
Private Methode öffnen
- ** Deep Reflection **: Erzwungener Zugriff durch Reflektion
 
- Eine tiefe Reflexion ist allein mit Modulexporten nicht möglich
 
import java.lang.reflect.InvocationTargetException;
import mylib.lib.MainLib;
public class ModuleClient2 {
  public static void main(String[] args) {
    try {
      var clazz = MainLib.class;
      var con = clazz.getConstructor();
      var m = con.newInstance();
      var name = clazz.getDeclaredField("name"); 
      name.setAccessible(true); //Error
      System.out.println(name.get(m));
    } catch (InstantiationException | IllegalAccessException |
        IllegalArgumentException | InvocationTargetException
        | NoSuchMethodException | SecurityException | NoSuchFieldException e) {
      e.printStackTrace();
    }
  }
}
Deklarieren Sie ein Paket mit ** öffnet Direktive ** und lösen Sie es!
- Veröffentlichen Sie das Paket nur zur Laufzeit
 
- Wenn Sie sich auf einen anderen Typ als Reflection beziehen, schließen Sie auch die Exportrichtlinie ein.
 
- ** 
open module mylib { ** öffnet alle Pakete unter dem Modul 
module-info.java
module mylib {
  opens mylib.lib;
  exports mylib.lib;
}
Spezialmodul
- Pseudomodul-Konzept wird ebenfalls bereitgestellt
 
- ** Automatikmodul **
 
- ** Anonymes Modul **
 
Automatisches Modul
- .Jar-Datei im Modulpfad
 
- Eine Bibliothek ohne 
module-info.java 
Bestimmt aus Manifestinformationen
- Setzt den im Attribut ** Automatischer Modulname ** der Manifestdatei (META-INF / MANIFEST.MF) angegebenen Namen auf den Modulnamen.
 
MANIFEST.MF
Manifest-Version: 1.0
Automatic-Module-Name: hoge.bar
Bestimmt durch den Dateinamen .jar
- Namensregeln
 
- Die Erweiterung 
.jar wurde entfernt 
- Wenn die Zeichen nach dem Bindestrich nur Zahlen / Punkte sind, löschen Sie sie nach dem Bindestrich
 
- Konvertieren Sie nicht alphanumerische Zeichen in "."
 
- Wiederholungspunkte sind einzelne Punkte, führende / nachfolgende Punkte werden entfernt
 
- Beispiel: hoge-bar-1.0.5.jar ist ** hoge.bar **
 
- Betriebsregeln
 
- ** Exportiert / öffnet alle Pakete darunter **
 
- ** Alle im Modulpfad registrierten Module und anonymen Module sind erforderlich **
 
- ** Erfordert die Verwendung von Paketen, die vom automatischen Modul aus anderen Modulen exportiert / geöffnet wurden **
 
Anonymes Modul
- .Jar-Datei im Klassenpfad platziert
 
- Hat keinen Modulnamen
 
- Zur Kompilierungszeit ** Kann nicht von Anwendungsmodulen referenziert werden **
 
- ** Kann von automatischen Modulen referenziert werden **
 
- ** Anwendungsmodul **: Modul mit module-info.java
 
- ** Plattformmodul **: Module, aus denen die Standardbibliothek besteht
 
Koexistenz mit Nicht-Modul-Bibliotheken
- ** Verwenden Sie Nicht-Modul-Bibliotheken aus modularen Apps **
 
- Die folgende ** Gson-Bibliothek ** konvertiert Java-Objekte in JSON-formatierte Zeichenfolgen
 
- java.sql-Paket abhängig
 
- Tiefe Reflexion über das zu konvertierende Java-Objekt
 
- Auf die Klasse java.sql.Time kann nicht ohne Verweis auf das von Gson intern verwendete Modul java.sql zugegriffen werden.
 
//NG-Beispiel Laufzeitfehler
import com.google.gson.Gson;
public class NoModuleLib {
  public static void main(String[] args) {
    var g = new Gson();
    var a = new Article("Java 11 ändert sich", "https://codezine.jp/article/corner/751");
    //Geben Sie das Ergebnis der Konvertierung des Objektinhalts in JSON aus
    System.out.println(g.toJson(a));
  }
}
Article.java
public class Article {
  private String title;
  private String url;
  public Article(String title, String url) {
    this.title = title;
    this.url = url;
  }
  @Override
  public String toString() {
    return String.format("Titel:%s(%s)",
        this.title, this.url);
  }
}
Fügen Sie der Ausführungsoption explizit ein Modul hinzu
- Im VM-Argument der Ausführungskonfiguration
 
- ** 
--add-opens = Modulname / Paketname = zulässige Module **
--add-modules=java.sql --add-opens=foo/example=gson 
 
- Machen Sie das Beispielpaket des foo-Moduls über die gson-Bibliothek zugänglich