
Java 教程
- Java - 首頁
- Java - 概述
- Java - 歷史
- Java - 特性
- Java vs. C++
- JVM - Java 虛擬機器
- Java - JDK vs JRE vs JVM
- Java - Hello World 程式
- Java - 環境設定
- Java - 基本語法
- Java - 變數型別
- Java - 資料型別
- Java - 型別轉換
- Java - Unicode 系統
- Java - 基本運算子
- Java - 註釋
- Java - 使用者輸入
- Java - 日期和時間
Java 控制語句
- Java - 迴圈控制
- Java - 決策制定
- Java - if-else
- Java - switch
- Java - for 迴圈
- Java - for-each 迴圈
- Java - while 迴圈
- Java - do-while 迴圈
- Java - break
- Java - continue
面向物件程式設計
- Java - OOPs 概念
- Java - 物件和類
- Java - 類屬性
- Java - 類方法
- Java - 方法
- Java - 變數作用域
- Java - 建構函式
- Java - 訪問修飾符
- Java - 繼承
- Java - 聚合
- Java - 多型
- Java - 方法重寫
- Java - 方法過載
- Java - 動態繫結
- Java - 靜態繫結
- Java - 例項初始化塊
- Java - 抽象
- Java - 封裝
- Java - 介面
- Java - 包
- Java - 內部類
- Java - 靜態類
- Java - 匿名類
- Java - 單例類
- Java - 包裝類
- Java - 列舉
- Java - 列舉建構函式
- Java - 列舉字串
Java 內建類
Java 檔案處理
Java 錯誤和異常
- Java - 異常
- Java - try-catch 塊
- Java - try-with-resources
- Java - 多重 catch 塊
- Java - 巢狀 try 塊
- Java - finally 塊
- Java - throw 異常
- Java - 異常傳播
- Java - 內建異常
- Java - 自定義異常
Java 多執行緒
- Java - 多執行緒
- Java - 執行緒生命週期
- Java - 建立執行緒
- Java - 啟動執行緒
- Java - 執行緒連線
- Java - 執行緒命名
- Java - 執行緒排程器
- Java - 執行緒池
- Java - 主執行緒
- Java - 執行緒優先順序
- Java - 守護執行緒
- Java - 執行緒組
- Java - 關閉鉤子
Java 同步
Java 網路程式設計
- Java - 網路程式設計
- Java - 套接字程式設計
- Java - URL 處理
- Java - URL 類
- Java - URLConnection 類
- Java - HttpURLConnection 類
- Java - Socket 類
- Java - 泛型
Java 集合
Java 介面
Java 資料結構
Java 集合演算法
高階 Java
- Java - 命令列引數
- Java - Lambda 表示式
- Java - 傳送郵件
- Java - Applet 基礎
- Java - Javadoc 註釋
- Java - 自動裝箱和拆箱
- Java - 檔案不匹配方法
- Java - REPL (JShell)
- Java - 多發行版 JAR 檔案
- Java - 私有介面方法
- Java - 內部類菱形運算子
- Java - 多解析度影像 API
- Java - 集合工廠方法
- Java - 模組系統
- Java - Nashorn JavaScript
- Java - Optional 類
- Java - 方法引用
- Java - 函式式介面
- Java - 預設方法
- Java - Base64 編碼解碼
- Java - switch 表示式
- Java - Teeing 收集器
- Java - 微基準測試
- Java - 文字塊
- Java - 動態 CDS 歸檔
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指標異常
- Java - 打包工具
- Java - 密封類
- Java - 記錄類
- Java - 隱藏類
- Java - 模式匹配
- Java - 簡潔數字格式化
- Java - 垃圾收集
- Java - JIT 編譯器
Java 雜項
- Java - 遞迴
- Java - 正則表示式
- Java - 序列化
- Java - 字串
- Java - Process API改進
- Java - Stream API改進
- Java - 增強的 @Deprecated 註解
- Java - CompletableFuture API改進
- Java - 流
- Java - 日期時間 API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java APIs 和框架
Java 類引用
- Java - Scanner
- Java - 陣列
- Java - 字串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用資源
Java - 模組系統
在 Java 9 中,引入了模組系統來增強 Java 程式碼的模組化。模組是對包的一種抽象。這個模組系統也稱為JPMS,Java 平臺模組系統。它通常被稱為模組。
什麼是模組?
模組是一個自描述的程式碼和資料集合,並具有一個名稱來標識它。它是一種新型的程式設計元件,可以包含包、配置和特定於特定功能的資源。模組能夠限制對其包含包的訪問。預設情況下,模組中包中的程式碼對外部世界不可見,即使透過反射也不行。從 Java 9 開始,Java 平臺本身就是模組化的。如果我們使用 list-modules 命令列出 Java 模組,它將列印 Java 支援的各種模組,如下所示:
C:\Users\Mahesh>java --list-modules java.base@20.0.2 java.compiler@20.0.2 java.datatransfer@20.0.2 java.desktop@20.0.2 java.instrument@20.0.2 java.logging@20.0.2 java.management@20.0.2 java.management.rmi@20.0.2 java.naming@20.0.2 java.net.http@20.0.2 java.prefs@20.0.2 java.rmi@20.0.2 java.scripting@20.0.2 java.se@20.0.2 java.security.jgss@20.0.2 java.security.sasl@20.0.2 java.smartcardio@20.0.2 java.sql@20.0.2 java.sql.rowset@20.0.2 java.transaction.xa@20.0.2 java.xml@20.0.2 java.xml.crypto@20.0.2 jdk.accessibility@20.0.2 jdk.attach@20.0.2 jdk.charsets@20.0.2 jdk.compiler@20.0.2 jdk.crypto.cryptoki@20.0.2 jdk.crypto.ec@20.0.2 jdk.crypto.mscapi@20.0.2 jdk.dynalink@20.0.2 jdk.editpad@20.0.2 jdk.hotspot.agent@20.0.2 jdk.httpserver@20.0.2 jdk.incubator.concurrent@20.0.2 jdk.incubator.vector@20.0.2 jdk.internal.ed@20.0.2 jdk.internal.jvmstat@20.0.2 jdk.internal.le@20.0.2 jdk.internal.opt@20.0.2 jdk.internal.vm.ci@20.0.2 jdk.internal.vm.compiler@20.0.2 jdk.internal.vm.compiler.management@20.0.2 jdk.jartool@20.0.2 jdk.javadoc@20.0.2 jdk.jcmd@20.0.2 jdk.jconsole@20.0.2 jdk.jdeps@20.0.2 jdk.jdi@20.0.2 jdk.jdwp.agent@20.0.2 jdk.jfr@20.0.2 jdk.jlink@20.0.2 jdk.jpackage@20.0.2 jdk.jshell@20.0.2 jdk.jsobject@20.0.2 jdk.jstatd@20.0.2 jdk.localedata@20.0.2 jdk.management@20.0.2 jdk.management.agent@20.0.2 jdk.management.jfr@20.0.2 jdk.naming.dns@20.0.2 jdk.naming.rmi@20.0.2 jdk.net@20.0.2 jdk.nio.mapmode@20.0.2 jdk.random@20.0.2 jdk.sctp@20.0.2 jdk.security.auth@20.0.2 jdk.security.jgss@20.0.2 jdk.unsupported@20.0.2 jdk.unsupported.desktop@20.0.2 jdk.xml.dom@20.0.2 jdk.zipfs@20.0.2 C:\Users\Mahesh>
在這裡我們可以看到,jdk 特定的包在 jdk 模組中,庫特定的包在 java 模組中。
Java 模組系統的特性
使用模組元件,在 Java 9 中添加了以下增強功能:
引入了一個新的可選階段,連結時間。此階段介於編譯時間和執行時間之間。在此階段,可以組裝和最佳化一組模組,使用 jlink 工具建立自定義執行時映像。
javac、jlink 和 java 具有其他選項來指定模組路徑,這些路徑進一步定位模組的定義。
JAR 格式更新為模組化 JAR,其根目錄中包含 module-info.class 檔案。
引入了JMOD 格式,這是一種打包格式(類似於 JAR),可以包含原生代碼和配置檔案。
宣告模組
為了宣告一個模組,我們需要在應用程式的根資料夾中建立一個 module-info.java 檔案。此檔案包含所有元資料或模組描述。
示例
module-info.java
module com.tutorialspoint.greetings { }
新增依賴模組
我們可以在模組中宣告其他模組的依賴項。例如,如果我們想使用 com.tutorialspoint.util 模組,我們可以新增如下宣告:
示例
module com.tutorialspoint.greetings { requires com.tutorialspoint.util; }
新增可選模組
我們可以使用模組中的 static 關鍵字宣告其他模組的可選依賴項。例如,如果我們想使用 com.tutorialspoint.logging 模組,我們可以新增如下宣告:
示例
module com.tutorialspoint.greetings { requires com.tutorialspoint.util; requires static com.tutorialspoint.logging; }
新增傳遞模組
我們可以使用模組中的 transitive 關鍵字宣告其他模組的傳遞依賴項。例如,如果我們想將 com.tutorialspoint.base 模組用作 com.tutorialspoint.util 模組的依賴項,我們可以新增如下宣告:
示例
module com.tutorialspoint.greetings { requires com.tutorialspoint.util; requires static com.tutorialspoint.logging; requires transitive com.tutorialspoint.base; }
這意味著如果一個模組想要使用 com.tutorialspoint.greetings,那麼該模組也需要在模組宣告中新增 com.tutorialspoint.base 模組。
匯出公共類
預設情況下,模組的包的任何公共類都不會公開給外部世界。為了使用公共類,我們必須像下面這樣匯出它:
示例
module com.tutorialspoint.greetings { requires com.tutorialspoint.util; requires static com.tutorialspoint.logging; requires transitive com.tutorialspoint.base; exports com.tutorialspoint.greetings.HelloWorld; }
允許反射
預設情況下,模組的包的任何私有成員都不能透過反射訪問。為了允許反射檢查類或模組,我們必須使用 opens 命令,如下所示:
示例
module com.tutorialspoint.greetings { requires com.tutorialspoint.util; requires static com.tutorialspoint.logging; requires transitive com.tutorialspoint.base; exports com.tutorialspoint.greetings.HelloWorld; opens com.tutorialspoint.greetings.HelloWorld; }
如果我們需要允許整個模組對反射開放,我們可以使用 open 命令,如下所示:
open module com.tutorialspoint.greetings { requires com.tutorialspoint.util; requires static com.tutorialspoint.logging; requires transitive com.tutorialspoint.base; exports com.tutorialspoint.greetings.HelloWorld; }
建立和使用 Java 模組
按照以下步驟建立一個名為 com.tutorialspoint.greetings 的模組。
步驟 1
建立一個資料夾 C:\>JAVA\src。現在建立一個與我們正在建立的模組名稱相同的資料夾 com.tutorialspoint.greetings。
步驟 2
在 C:\>JAVA\src\com.tutorialspoint.greetings 資料夾中建立 module-info.java 檔案,其中包含以下程式碼。
module-info.java
module com.tutorialspoint.greetings { }
module-info.java 是用於建立模組的檔案。在此步驟中,我們建立了一個名為 com.tutorialspoint.greetings 的模組。按照約定,此檔案應該位於名稱與模組名稱相同的資料夾中。
步驟 3
將原始碼新增到模組中。在 C:\>JAVA\src\com.tutorialspoint.greetings\com\tutorialspoint\greetings 資料夾中建立 Java9Tester.java 檔案,其中包含以下程式碼。
Java9Tester.java
package com.tutorialspoint.greetings; public class Java9Tester { public static void main(String[] args) { System.out.println("Hello World!"); } }
按照約定,模組的原始碼位於與模組名稱相同的目錄中。
步驟 4
建立一個資料夾 C:\>JAVA\mods。現在建立一個與我們建立的模組名稱相同的資料夾 com.tutorialspoint.greetings。現在將模組編譯到 mods 目錄。
C:/ > JAVA > javac -d mods/com.tutorialspoint.greetings src/com.tutorialspoint.greetings/module-info.java src/com.tutorialspoint.greetings/com/tutorialspoint/greetings/Java9Tester.java
步驟 5
讓我們執行模組以檢視結果。執行以下命令。
C:/>JAVA>java --module-path mods -m com.tutorialspoint.greetings/com.tutorialspoint.greetings.Java9Tester
此處 module-path 提供模組位置為 mods,-m 表示主模組。
它將在控制檯列印以下輸出。
Hello World!