Java 9,Jigsaw,JPMS和模块:个人探索
Java 9由于Jigsaw項目而延遲了很多次,您可能會聽到很多關于模塊,模塊化和其他內容的信息,那么,它的全部含義是什么? 模塊化到底是什么,模塊化平臺是什么意思? Java平臺模塊系統(JPMS)? 這將是Java生態系統的一場革命嗎?
這篇文章是我對JDK模塊系統最重要的事情的探索。 我將解釋什么是模塊化,為什么需要模塊化以及如何創建模塊化項目。
什么為什么:
可維護性是軟件設計和開發中最重要的問題之一。 我們需要一個松散耦合,高度內聚,極易讀且可以一眼就能理解的代碼庫。 我們設計課程并將其整理在包中。 到目前為止,一切都很好,但是當我們有數百個軟件包時, 它們之間的依賴關系就無法一目了然。 因此,我們需要的不僅僅是軟件包,而是用于組織代碼庫并使之更易于維護的代碼。
另一個問題是java類路徑及其如何運行我們的代碼。 所有jar類和庫都被展平到類路徑中。 當這些jar文件在運行時具有一個類的多個版本時,Java ClassLoader只能加載該類的一個版本,這樣,對于程序的工作方式將有歧義,并且歧義是一件壞事。 這個問題如此頻繁,以至于它的名字叫做“ JAR Hell” 。
類路徑的另一個問題是它不遵循“失敗優先”原則。 您可能缺少類路徑中存在的類,但是在生產環境中不存在。 直到運行時出現JavaClassDefError異常 ,您才能確定缺少什么。 最后,類路徑的最大問題是封裝。 類路徑上的每個類都互相訪問,這是封裝違規。 我們想隱藏我們的內部API,這就是為什么我們需要另一級別的封裝( “強封裝” )并控制對包中類的訪問的原因。
模塊將解決這些問題。 什么是模塊? 模塊有一個名稱,它對相關代碼進行分組并且是獨立的。 一個模塊明確描述了其他模塊需要的內容,以及其他模塊可見的部分。 以這種方式,模塊之間的依賴性非常清晰。 我們具有強大的封裝功能,這意味著我們可以隱藏我們的內部API,最后,我們現在遵循“故障優先”的原則,因此,當缺少模塊或沖突時,您將得到一個錯誤。
模塊化JDK使JDK開發人員可以管理它的巨大復雜性。 當您編寫一個不使用RMI,CORBA,JavaEE等其他東西的小型直接應用程序時,為什么需要一個完整,龐大而又繁重的Java運行時環境? 僅包含所需模塊的運行時映像不是更明智嗎? 現在有了模塊化平臺,這是可能的。
這就是JDK現在的樣子。 在底部,我們有“ java.base ”模塊,每個其他模塊都隱式或顯式依賴該模塊。 如您所見,此依賴關系圖是DAG ,這意味著不允許循環依賴。
下圖實質上顯示了什么是模塊。 每個模塊都有一個稱為“ module-info.java”的模塊描述符。
在module-info.java文件中,您描述了模塊的名稱,工作所需的條件以及在該模塊外部可見的軟件包。 例如,您可以看到java.sql導出了哪些包(使其可見)以及需要哪些模塊。
因此,以最簡單的形式,module-info.java如下圖所示:
在下一節中,我將展示如何使用這些模塊并創建模塊。
怎么樣:
首先,您需要下載并安裝Java9。您可以在此處找到它。
Java版本
$ java -version java version "9" Java(TM) SE Runtime Environment (build 9+181) Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode讓我們在IntelliJ IDEA中構建一個項目:
下圖顯示了如何創建模塊:
創建模塊后,您需要在src內創建一個module-info.java文件:
我已經建立了一個包含兩個模塊的項目:“ com.mhrimaz.gui”和“ com.mhrimaz.logic”。 您可以在圖像中看到項目的結構:
在com.mhrimaz.logic模塊中,我有兩個名為“ InternalGreeting”和“ Greeting”的類。
InternalGreeting.java
package com.mhrimaz.logic.internals;public class InternalGreeting {public static String sayHello(String name){return "Hello, This Greeting is internal dear "+ name;} }Greeting.java
package com.mhrimaz.logic;public class Greeting {public static String sayHello(String name){return "Hello, " + name;} }com.mhrimaz.logic的module-info.java如下:
module com.mhrimaz.logic {exports com.mhrimaz.logic; }這意味著軟件包com.mhrimaz.logic(它是軟件包名稱,不要混淆模塊名稱)在此模塊外部可見,但軟件包com.mhrimaz.logic.internals不可見。
MianApplication文件是一個簡單的JavaFX程序:
package com.mhrimaz.gui;import com.mhrimaz.logic.Greeting; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; import javafx.stage.Stage;public class MainApplication extends Application {@Overridepublic void start(Stage primaryStage) throws Exception {Label label = new Label(Greeting.sayHello("Hossein"));StackPane pane = new StackPane();pane.getChildren().add(label);Scene scene = new Scene(pane);primaryStage.setScene(scene);primaryStage.show();} }似乎此程序包不需要導出任何內容,它只需要javafx.base和javafx.controls,并且為了使用Greeting類,我們還需要com.mhrimaz.logic。 com.mhrimaz.gui模塊的module-info如下所示:
module com.mhrimaz.gui {requires javafx.base;requires javafx.controls;requires com.mhrimaz.logic; }當我們運行我們的應用程序時,我們將得到一個異常:
Caused by: java.lang.IllegalAccessException: class com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access class com.mhrimaz.gui.MainApplication (in module com.mhrimaz.gui) because module com.mhrimaz.gui does not export com.mhrimaz.gui to module javafx.graphics 因此很明顯,它表明我們需要導出com.mhrimaz.gui包,這意味著javafx.graphics使用MainApplication將舞臺傳遞給它,并且您需要將包導出到javafx.graphics(注意:您只能導出包特定模塊或將其導出到所有模塊)
所以現在module-info.java看起來像這樣:
結果似乎是Java 9中JavaFX實現中的錯誤,但這是我們的結果:
故事還沒有結束,有關模塊,模塊之間的依賴關系的大量詳細信息可以在Java 9 Revealed或Java 9 Modularity一書中閱讀。
翻譯自: https://www.javacodegeeks.com/2017/09/java-9-jigsaw-jpms-modules-personal-exploration.html
總結
以上是生活随笔為你收集整理的Java 9,Jigsaw,JPMS和模块:个人探索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你不知道的马斯克:通宵打游戏、谈变性儿子
- 下一篇: 中石科技为华为 Mate 60 系列手机