中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么實現Java模塊化系統的分析

發布時間:2021-12-27 16:20:40 來源:億速云 閱讀:248 作者:柒染 欄目:編程語言

這篇文章給大家介紹怎么實現Java模塊化系統的分析,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

Java 模塊化系統自提出以來經歷了很長的時間,直到 2014 年晚些時候才最終以 JSR(JSR-376) 定稿,而且這個部分有可能在 Java 9 中出現。但是一直以來都沒有可以使用的原型。9 月 11 日,OpenJDK 發布的早期構建版本終于包含了 Jigsaw 項目。

我和同事 Paul Bakker 在 JavaZone 上對于 Java 模塊化系統進行了討論。整個討論都建立在JSR-376   需求文檔以及身邊一些珍貴的信息上。在年初提出舉行這個報告的時候,我們曾深信不疑地認為在這個會上我們能夠展示一個原型,但是事情卻沒有按預想的那樣發 展。現在的情況是,這個原型將在我們的報告結束之后發布。這也意味著,報告中的一些內容已經有點過時了,但是主要的思想還是很有新意的。

為什么要使用模塊?

什么是模塊?我們為什又需要它們?如果希望有一個深入的討論,請閱讀“State of the module system”或者看一下我們的報告。對這塊還不是很了解的人來說,這里有Cliff 的注釋版本。

我們都知道 Java 有 jar 文件。但是,事實上這些都只是包含一些class(類)的壓縮文件,這些 jar 包內部都是一些  package (包)。當你利用一些不同的 jar  包來運行應用程序的時候(復雜一點的程序也適用),你需要把它們放到指定的類路徑中。然后默默祈禱。因為沒有有效的工具來幫助你知道,你是否已經把應用所 需要的 jar 包都放入類路徑中了。或者有可能你在不經意間將同樣的類文件(在不同的 jar 包中)都放入了類路徑中。類路徑災難(類似于 DLL  災難)是真實存在的。這會導致運行時出現糟糕的狀況。同時,在運行時我們也無法得知 jar 中包含哪些類。從 JRE  角度來說只知道有一堆類文件。事實上 jar 包之間是相互依賴的,但目前還不能把這種依賴關系記錄到數據文件中去。理想的情況是,你可以隱藏 jar  包中類文件具體的實現,只是提供一些公共的 API 。在 Java 中提出模塊化系統就是為了解決這些問題的:

  • 模塊成為首先要考慮的部分,它能夠分裝實現細節并且只暴露需要的接口。

  • 模塊準確地描述了他們能夠提供的接口,以及他們的需要部分(依賴)。由此,我們可以在開發的過程中弄清和處理依賴關系。

模塊系統極大地提升了大型系統的可維護性、可靠性、安全性。至少 JDK 本身還缺少這樣的系統。通過這樣的模塊系統,模塊圖能夠自動地構建。這個圖只包括了你的應用程序運行時所須要的模塊。

安裝 JDK9 預覽版

如果你想親自嘗試編寫示例代碼,你需要安裝包含 Jigsaw 原型的 JDK9 早期構建版本。在 OSX  上,你需要解壓文檔,然后把解壓出來的目錄移動到 Library/Java/JavaVirtualMachines/  下。然后你需要設置環境變量,將 JAVA_HOME 環境變量指向 JDK9 的目錄。我使用了非常好用的setjdk  腳本,通過它可以在命令窗口中實現 Java 安裝的命令切換。你很有可能不愿意使用這個早期構建版本作為你的 Java 安裝版本。你可以通過  java -version 來確認安裝完成。輸出如下面所示:

1

2

3

java version "1.9.0-ea"

Java(TM) SE Runtime Environment (build 1.9.0-ea-jigsaw-nightly-h4337-20150908-b80)

Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-jigsaw-nightly-h4337-20150908-b80, mixed mode)

只要輸出中包含 Jigsaw ,你就可以繼續了。文章后面的示例代碼可以去 https://github.com/sandermak/jigsaw-firstlook 下載。

一個簡單的例子

你仍舊可以通過類、jar包以及類路徑這樣“傳統方式”的方式來使用 JDK9 。但是明顯地我們想要采用模塊的方式。所以我們將創建一個包含兩個模塊的工程:模塊一使用了模塊二中的代碼。

首先要做的就是,構建我們的工程并把兩個模塊很好地區分開來。然后,模塊中需要以 module-info.java 文件的形式添加元數據。我們的示例構建如下:

1

2

3

4

5

6

7

src

  module1

     module-info.java

     comtestTestClassModule1.java

  module2

     module-info.java

     commoretestTestClassModule2.java

接著,我們將介紹 package (包)層最頂上的一層(module1、 module2),這部分你在之前已經構建好了。在這些“模塊目錄”中,可以看到 module-info.java 文件在根目錄下。此外請注意,這兩個類都是在顯示命名的包中的。

請看 TestClassModule1 的代碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

package com.test;

import com.moretest.TestClassModule2;

public class TestClassModule1 {

   public static void main(String[] args) {

     System.out.println("Hi from " + TestClassModule2.msg());

   }

}

看起來很普通對吧?這里并沒有涉及模塊,而是導入了 TestClassModule2 ,主函數之后會去調用其中的 msg() 方法。

1

2

3

4

5

6

7

8

9

10

11

package com.moretest;

public class TestClassModule2 {

   public static String msg() {

     return "from module 2!";

   }

}

到目前為止,module-info.java 還是空的。

對 Java 模塊進行編譯

現在進行下一步:編譯我們的模塊,并關聯源文件。為了做這項工作,我們將介紹一個新的 javac 編譯參數:

1

javac -modulesourcepath src -d mods $(find src -name '*.java')

使用上面語句時,我們假設命令程序已經處于 src 文件夾的上級目錄中了。-modulesourcepath 參數會讓 javac  從傳統編譯模式進入模塊模式。-d 標記指出了編譯好的模塊的輸出目錄。javac 將以非打包文件的形式輸出這些模塊。如果我們這之后想以 jars  的形式使用這些模塊的話,需要一個單獨的步驟。

那么當我們調用上面的 javac 命令行的時候會發生什么那?編譯出錯了!

1

2

src/module1/module-info.java:1: error: expected 'module'

src/module2/module-info.java:1: error: expected 'module'

空的 module-info.java  文件導致了這個錯誤。所以,一些新的關鍵字將被引入到這些文件中來,這些都是模塊中非常重要的部分。這些關鍵字的作用域就是  module-info.java 的定義部分。你還可以在 java 的源文件中使用 module 類型的變量。

我們采用了最少的描述信息,并更新了模塊描述文件:

1

module module1 { }

然后是模塊2:

1

module module2{ }

現在,模塊已經被準確地命名了,但是還沒有包含其它的數據。再次編譯會導致新的錯誤:

1

src/module1/com/test/TestClassModule1.java:3: error: TestClassModule2 is not visible because package com.moretest is not visible

封裝出現了!默認情況下,模塊內部的類或者其他類型對外都是隱藏的。這就是 javac 不允許使用 TestClassModule2  的原因,即使它是一個公共的類。如果我們還是使用基于傳統類路徑的編譯的話,一切都可以正常運作。當然我們也可以通過明確地將  TestClassModule2 暴露給外部來解決這個問題。接下來的這些改變對于 module2 中的 module-info.java  來說是必須的:

1

2

3

4

5

module module2 {

  exports com.moretest;

}

這還不夠。如果你將修改后的編譯,你會得到同樣的錯誤。那是因為,雖然現在 module2 已經暴露了所需的包(包含所有的公共類型),但是  module1 還沒有聲明它對 module2 的依賴。我們同樣可以改變 module1 的 module-info.java  文件來解決這個問題:

1

2

3

4

5

module module1 {

   requires module2;

}

通過指定名字的方法可以表示對其它模塊的依賴,盡管在這些模塊中是以包的形式導出的。這方面還有很多可以說的東西,但是我并不想在初步的介紹中涉 及。在做完這一步之后,我們使用 Jigsaw ***次成功編譯了多模塊項目。如果你打開 /mods  目錄,你能看到編譯出來的東西被整齊地劃分為兩個目錄。這就成功了!

運行模塊化代碼

只是編譯的話并沒有多大樂趣。我們希望應用程序能夠運行起來。幸運的是,JRE 和 JDK 已經在這個原型中支持模塊關聯。這個應用可以通過指定模塊路徑的方式來啟動,而不是類路徑:

1

java -mp mods -m module1/com.test.TestClassModule1

我們把模塊路徑指向 mods 文件夾,這個文件就是 javac 編譯時寫輸出模塊的地方。而 -m 指出了最初要啟動的模塊,通過這個模塊可以逐步啟動其他模塊。我們同樣添加了在初始化時需要調用的啟動類的名字,運行結果如下所示:

1

Hi from from module 2!

關于怎么實現Java模塊化系統的分析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

中江县| 九龙城区| 大姚县| 依兰县| 呼玛县| 微博| 冷水江市| 高淳县| 西乡县| 冕宁县| 西华县| 东乡族自治县| 丽江市| 商城县| 天峻县| 虞城县| 沙雅县| 五常市| 开封市| 益阳市| 来宾市| 施秉县| 酒泉市| 崇文区| 西安市| 巩留县| 府谷县| 丹棱县| 射洪县| 新昌县| 高平市| 思茅市| 枝江市| 霸州市| 清水县| 南安市| 湟中县| 九江县| 宜川县| 静安区| 江陵县|