0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Java的模塊系統(tǒng)定義

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-10-11 16:01 ? 次閱讀

前言

對于模塊的定義,相信小伙伴們都不會有太大的疑問,這里引用JDK中模塊的定義:一組可重用的相關包和資源,以及模塊的描述信息。直白點的描述就是:用一種比package更大級別的組織方法來管理我們的類。講到它的作用是組織管理,大家是不是就開始聯(lián)想到了OSGi,JBoss Module,Maven,甚至是微服務呢?首先,這幾種形式都是用于軟件的模塊化方法,只是應用的場景和各自的長處有所不同,指北君用一張圖表來做一下簡單對比:

圖片
模塊化方式

  • 微服務:服務粒度的組織方法,比模塊級別更高
  • Maven:依賴管理工具

變化

首先,作為一頭猿,最直接的編碼IDE工具,以Eclipse為例,我們新建一個標準的Java工程,切換下JDK進行對比,

圖片
JDK庫-JAVA11

圖片
JDK庫-JAVA8

首先我們會發(fā)現(xiàn):項目使用中的JDK11的庫中比之前JDK8多出很多條目來,而且和之前的完全不一樣了。這就是JDK引入模塊后,將原來的庫進行了拆分。為什么要拆呢?

  1. 伴隨Java的版本升級,包越來越多,功能越來越多,組織管理越來越難
  2. 一些jar包太大(比如rt.jar),不利于在小型設備中運行
  3. 無法定義只能在模塊內部訪問的接口,只能通過一些額外的約束,比如文檔,internal等形式進行提示

JDK是如何對原有的jar進行拆分的呢?我們查看模塊名稱會發(fā)現(xiàn),所有模塊分成兩類:java開頭和jdk開頭,這是按照JAVA的JRE和JDK范圍進行的大類別的劃分,然后再按照功能級做進一步劃分。除了在開發(fā)者環(huán)境中引入的庫發(fā)生變化外,在JDK的安裝目錄中也有類似的變化

圖片
JDK安裝目錄對比

明顯是jre目錄不在了,增加了jmods目錄,lib下面的組織形式也發(fā)生了較大的變化。

可以做什么

前面我們介紹模塊系統(tǒng)引入后帶來的直觀的變化,這一節(jié)指北君要介紹模塊系統(tǒng)的作用,我們先來看一下模塊的定義里面包含的要素:

  • 名稱 – 模塊名
  • 依賴 - 本模塊依賴的一系列其他模塊
  • 公共包 - 外部可訪問的所有包
  • 提供的服務 - 提供其他模塊消費的服務實現(xiàn)
  • 消費的服務 - 允許當前模塊作為服務消費者
  • 反射權限 - 顯式允許其他類通過反射訪問的包的私有成員

從定義的要素中我們發(fā)現(xiàn):模塊不僅僅是提供的一直包、類的組織方式,更重要的是提供了以前無法支持的安全訪問控制。

模塊的類型

有四種類型的模塊

  • 系統(tǒng)模塊:JDK定義的模塊,可以通過下面命令來獲取
java --list-modules
  • 應用模塊:我們開發(fā)的應用對應的模塊,通過module-info.java定義并編譯成對應的class
  • 自動模塊:通過模塊路徑加載的第三方jar包
  • 未命名模塊:不是通過模塊路徑加載的第三方jar

模塊的聲明

要創(chuàng)建一個模塊,需要在包的根路徑下創(chuàng)建module-info.java(注意名稱是固定的),如果按照Class的方式創(chuàng)建會出現(xiàn)名稱校驗失敗,這時候可以直接創(chuàng)建一個文件命名為module-info.java。

module moduleName {
    
}

使用關鍵字module定義,模塊名稱按照約定為通過點號"."分割的小寫詞組,比如java.base, north.sample。

requires

requires用來管理模塊的依賴關系,我們一旦采用了模塊,我們會發(fā)現(xiàn)原來的有些類會出現(xiàn)編譯錯誤,這是因為我們的代碼中應用了默認之外的包,需要通過requires關鍵詞引入我們引用的模塊。

module north.smaple{
    requires java.scripting;
    
}

使用requires還可以使用兩個修飾詞:static,transitive,

  • static用來定義一個可選的模塊依賴,僅當編譯時有依賴才引用
  • transitive 表示下游的模塊不用顯式聲明,就可以使用上級模塊中通過transitive關鍵字引入的模塊

exports

通過exports我們可以定義可訪問的接口

module north.smaple{ 
    exports north.jdk.scripting;
}

我們還可以通過exports…to來定義接口開放的目標對象。

uses

定義使用的服務,以java.sql模塊代碼為例:

module java.sql {
    ...

    exports java.sql;
    exports javax.sql;

    uses java.sql.Driver;
}

為什么對服務特殊處理呢?各位小伙伴是不是覺得:requires就能夠定義訪問依賴,為啥還要用uses呢?這是因為,uses相對于requires是存在區(qū)別的。比如,我們的服務接口實現(xiàn)和服務接口不在同一個模塊中,如果用requires則需要對所有的實現(xiàn)模塊引入,如果使用uses只需要引入接口所在的模塊就行了,是不是很方便呢!而且有時我們都不知道接口的實現(xiàn)模塊,這時候都無法通過requires引入。

provide

如果需要定義外部可使用的服務,則通過provide聲明,語法是 provides <服務接口> with <服務實現(xiàn)>

module north.smaple{
    provides ISampleService with ISampleServiceImpl;
}

open/opens

open是用來定義模塊的被外部模塊通過反射調用的權限,在這之前我們可以通過反射調用任何我們想要訪問的類型和成員,甚至是私有屬性的。在使用模塊系統(tǒng)后,如果我們要保持之前的全訪問,可以直接在module前添加open關鍵字。

open module north.smaple{
    ...
}

如果我們有針對性的開放反射權限,則通過opens

module north.smaple{
    opens north.jdk.scripting;
}

opens還支持更嚴格的定義 opens ... to ...

總結

關于Java的模塊系統(tǒng),我們今天就學習到這里,相信經(jīng)過代碼示例和講解,各位小伙伴已經(jīng)可以將模塊系統(tǒng)應用到項目中了。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 模塊
    +關注

    關注

    7

    文章

    2613

    瀏覽量

    47006
  • JAVA
    +關注

    關注

    19

    文章

    2943

    瀏覽量

    104096
  • 軟件
    +關注

    關注

    69

    文章

    4570

    瀏覽量

    86695
  • 編碼
    +關注

    關注

    6

    文章

    915

    瀏覽量

    54651
收藏 人收藏

    評論

    相關推薦

    Java Security的核心模塊和代碼演示

    ,包括其核心概念、關鍵模塊以及具體應用。通過詳細分析,希望幫助讀者更好地理解如何在Java應用程序中實現(xiàn)安全防護,提高系統(tǒng)的可靠性和穩(wěn)定性。 主要功能包括授權、訪問控制、數(shù)據(jù)加密、身份驗證等 核心
    的頭像 發(fā)表于 10-07 15:44 ?977次閱讀

    基于JAVA與SSM的移動電源租賃系統(tǒng)的設計

    涉及到的關鍵設計思想及重要作業(yè)流程作了具體分析和介紹,并對各個模塊的設計思想及設計過程作了詳細闡述。本系統(tǒng)的設計采用了JAVA技術,SSM框架,三層架構,以Oracle作為數(shù)據(jù)庫支撐平臺。該
    發(fā)表于 01-03 07:08

    Java語言基礎

    Java語言基礎4.1 Java 程序的構成4.2 數(shù)據(jù)類型、變量與常量4.3 表達式4.4 流程控制語句Java源程序是由類組成的,每個程序中可以定義若干個類,但只能有一個主類。在
    發(fā)表于 12-14 20:30 ?187次下載

    基于JAVA的ICQ系統(tǒng)的源代碼

    基于JAVA的ICQ系統(tǒng) 服務器與客戶間通過套接口Socket(TCP)連接。在java中使用套接口相當簡單,Java API為處理套接口的通信提供了一個類
    發(fā)表于 03-10 13:39 ?13次下載

    JAVA制作的ICQ系統(tǒng)

    JAVA制作的ICQ系統(tǒng)   基于JAVA的ICQ系統(tǒng)服務器與客戶間通過套接口Socket(TCP)連接
    發(fā)表于 03-29 14:12 ?21次下載

    模塊Java:動態(tài)模塊

    在前一篇文章《模塊Java:靜態(tài)模塊化》中,我們討論了如何構建Java模 塊并將其作為一個單獨的JAR進行部署。文中的例子給出了一個client和一個 server bundle(兩
    發(fā)表于 12-01 11:54 ?24次下載

    JAVA教程之自定義光標

    JAVA教程之自定義光標,很好的學習資料。
    發(fā)表于 03-31 11:13 ?7次下載

    Java 9的新特性詳解

    JDK 9的Java平臺模塊系統(tǒng) Java 9最寶貴的特性,即模塊化以Java平臺
    發(fā)表于 09-28 14:37 ?0次下載

    Java 9的新特性總結

    模塊系統(tǒng)Jigsaw 項目 模塊化是一個很通用的概念。在軟件中,模塊化可以運用到編寫和實現(xiàn)一個程序和計算系統(tǒng),他們都是作為獨立的
    發(fā)表于 09-28 20:04 ?0次下載
    <b class='flag-5'>Java</b> 9的新特性總結

    java中數(shù)組的三種定義方式_java中數(shù)組的定義及使用方法(推薦)

    java中,數(shù)組是一種很常用的工具,本文將介紹來java中數(shù)組的三種定義方式以及java中數(shù)組的定義及使用方法。
    發(fā)表于 01-29 09:53 ?3.2w次閱讀

    Java定義常量兩種常見策略

    關于Java中常量的話題似乎有很多困惑。有些人使用整數(shù)或字符串來定義常量,而另一些人則使用枚舉。
    的頭像 發(fā)表于 05-05 20:49 ?2258次閱讀
    在<b class='flag-5'>Java</b>中<b class='flag-5'>定義</b>常量兩種常見策略

    針對系統(tǒng)提供商最具挑戰(zhàn)性需求的自定義模塊

    針對系統(tǒng)提供商最具挑戰(zhàn)性需求的自定義模塊
    發(fā)表于 04-26 16:15 ?4次下載
    針對<b class='flag-5'>系統(tǒng)</b>提供商最具挑戰(zhàn)性需求的自<b class='flag-5'>定義</b><b class='flag-5'>模塊</b>

    Java、SSM移動電源租賃系統(tǒng)的設計與實現(xiàn)

    涉及到的關鍵設計思想及重要作業(yè)流程作了具體分析和介紹,并對各個模塊的設計思想及設計過程作了詳細闡述。本系統(tǒng)的設計采用了JAVA技術,SSM框架,三層架構,以Oracle作為數(shù)據(jù)庫支撐平臺。該
    發(fā)表于 01-12 12:43 ?10次下載
    <b class='flag-5'>Java</b>、SSM移動電源租賃<b class='flag-5'>系統(tǒng)</b>的設計與實現(xiàn)

    java源程序是由類定義組成的嗎

    Java源程序是由類定義組成的。在Java中,類是用來定義對象的一種結構化方式。一個類可以包含字段(變量)和方法(函數(shù)),它們一起描述了對象的屬性和行為。 在
    的頭像 發(fā)表于 11-28 16:36 ?530次閱讀

    java中長整型怎么定義

    Java中,長整型是一種數(shù)據(jù)類型,用于存儲整數(shù)值。它的取值范圍比整型要大,可以存儲更大的整數(shù)值。長整型的大小為8字節(jié),即64位。在Java中,長整型用關鍵字"long"進行聲明和定義。 在J
    的頭像 發(fā)表于 11-30 11:29 ?2743次閱讀