Java基礎-模塊系統筆記(1)

個人博客 轉載請註明原創出處。

Java 9開始,在Java的世界裏多了一個叫模塊(JSR376)的特性。模塊系統的前身是Jigsaw項目。最初,該項目僅僅是爲JDK設計、實現一個模塊系統。後來項目組也但願它能爲開發者所用——雖然,一開始它並非Java SE平臺規範的組成部分。隨着項目的不斷深刻,Java平臺對標準模塊系統的呼求也日益增加,JCP批准該項目升級爲JavaSE平臺的一部分,也能服務於Java MEJava EE平臺的需求。java

官方對Java平臺模塊系統是這樣描述的:

一種新的Java編程組件,即模塊。它是自描述的代碼與數據的集合,有如下特性:

  • 引入了一個新的可選階段——連接時,它介於編譯時和運行時之間,在此期間能夠將一組模塊組裝並優化爲定製的運行時鏡像。
  • 爲工具javacjlink增長了一些選項,以及在Java中,你能夠指定模塊路徑,這些路徑定位模塊的定義。
  • 引入模塊化JAR文件,該文件是一個JAR文件,其根目錄中包含module-info.class文件。
  • 引入JMOD格式,它是一種相似於JAR的打包格式,但它能夠包含原生代碼和配置文件。

JDK自己已經模塊化。有如下改變:

  • 使你可以將JDK的模塊組合成各類配置,包括:編程

    • JREJDK同樣的配置。
    • Java SE 8中定義的每一個壓縮配置文件的內容大體相同。
    • 自定義的配置,僅包含一組指定的模塊及其所需的模塊。
  • 重構JDKJRE運行時鏡像以適應模塊並提升性能、安全性和可維護性。
  • 定義了一個新的URI方案,用於命名存儲在運行時映像中的模塊,類和資源,而不會泄露映像的內部結構或格式。
  • 刪除承認的標準覆蓋機制和擴展機制。
  • Java運行時鏡像中刪除rt.jartools.jar
  • 默認狀況下,大多數JDK的內部API都不可訪問,但在全部或大部分功能都支持替換以前,能夠訪問一些關鍵的、普遍使用的內部API

運行jdeps -jdkinternals命令以肯定你的的代碼是否使用了內部JDK API安全

兼容性

先來講說模塊系統的兼容性。Java一直是比較保守的,體如今更新上就是良好的兼容性。雖然看了官方對Java平臺模塊系統的描述好像改動很是大,可是你的舊項目即便不模塊化也是能在新JDK上運行的。後面會講到沒有模塊化的類包是如何與模塊交互的。框架

爲何要模塊化

既然不模塊化也能好好的運行,那麼爲何要這麼大費周章的折騰代碼呢?ide

第一點,Java 9前的Java程序,即便是一個簡單的輸出Hello World的程序,也必須將整個JDKJRE運行時鏡像打包進去才能運行,這時Java引覺得傲的數量繁多的類庫反而成了累贅。好比開源的優秀編程庫——Guava裏有不少很實用的工具類,有時咱們可能只用到了其中一個類而已,卻不得不將整個Guava類庫打包進咱們的項目。模塊化

第二點,無法定義類是否能被其餘包裏的類引用到。好比咱們編寫了一個工具類,若是但願這個類只能被某些包裏的其餘類引用到,不暴露給其餘包,Java 9前的Java程序是作不到這一點的。工具

如何模塊化

模塊化一個項目只要在項目的根目錄建立一個module-info.class文件就能夠了。性能

如圖所示,咱們建立了一個名爲module的模塊並用關鍵字exports導出了test包。若是有其餘模塊導入module模塊就能夠引用到Main類了,值得注意的是和test同級的包和test內部的包由於沒有被導出,都是不能被引用到的。優化

而引用一個模塊則是用關鍵字requiresui

而後就可使用test包內的類了:

import test.Main;

/**
 * @author Yuicon
 */
public class Test {

    public static void main(String[] args) {
        Main main = new Main();
        System.out.println(main);
    }

}

不過在導入前還須要在模塊依賴裏添加要導入的模塊:

java.base模塊是默認導入的,裏面有咱們經常使用的類庫:

模塊的強封裝性

咱們知道模塊化後就能控制那些包能夠被引用到了。不過不止如此,一個模塊的類是不能訪問到其餘模塊裏的類的私有屬性的。聽起來好像是理所固然的,這是由於原先咱們是能夠用反射來訪問到私有屬性的。模塊化後就算反射也不能訪問到了,算是增強了安全性。

不過這樣的話,那些依賴反射來獲取私有屬性的框架和庫就倒黴了。爲了兼容這些框架和庫,咱們能夠在模塊定義里加一個關鍵字open

module-info.class

open module module {
    exports test;
}

這樣咱們就聲明瞭一個開放的模塊,在模塊的全部軟件包上授予深刻的反射訪問權限(訪問公共和私有API)。

模塊語句

在模塊聲明文件裏一共有五種模塊語句,分別是:

  • 導出語句(exports statement)
  • 開放語句(opens statement)
  • 須要語句(requires statement)
  • 使用語句(uses statement)
  • 提供語句(provides statement)

package test.driver;

/**
 * @author Yuicon
 */
public interface Driver {

    int getCode();

}
package test;


import test.driver.Driver;


/**
 * @author Yuicon
 */
public class DriverImpl implements Driver {

    @Override
    public int getCode() {
        return 10086;
    }
}
module module {
    exports test.driver; // 導出包
    provides Driver
            with DriverImpl; // 爲接口Driver提供實現
}

module queue {
    requires module; // 導入包
    opens test; // 開放包的反射權限
    uses Driver; // 聲明使用接口
}
package main;

import test.driver.Driver;

import java.util.ServiceLoader;


/**
 * @author Yuicon
 */
public class Main {

    public static void main(String[] args) {
        // 獲取實現
        ServiceLoader<Driver> serviceLoader = ServiceLoader.load(Driver.class);
        serviceLoader.findFirst().ifPresent(driver -> System.out.println(driver.getCode()));
    }

}

輸出:

10086

Process finished with exit code 0

聚合模塊

你能夠建立一個不包含任何代碼的模塊,它收集並從新導出其餘模塊的內容,這樣的模塊稱爲聚合模塊。假設有幾個模塊依賴於五個模塊,你能夠爲這五個模塊建立一個聚合模塊。如今,你的模塊只能依賴於一個模塊——聚合模塊。

爲了方便,Java 9包含幾個聚合模塊,如java.sejava.se.eejava.se模塊收集Java SE的不與Java EE重疊的部分。java.se.ee模塊收集組成Java SE的全部模塊,包括與Java EE重疊的模塊。

待續

相關文章
相關標籤/搜索