【Java 基础篇】Java 模块化详解

在这里插入图片描述

Java 9引入了一项重要的功能:模块化(Module System)。模块化是一种将代码和资源封装到可重用和独立的单元中的方法,它有助于改善代码的可维护性、可重用性和安全性。本文将介绍Java模块化的基本概念、如何创建和使用模块以及一些最佳实践。

什么是Java模块化?

在Java 9之前,Java应用程序是以JAR文件的形式组织的,其中包含了一堆类和资源。这种方式存在一些问题:

  • 可维护性差:JAR文件可以包含大量的类和资源,这使得应用程序的结构变得混乱,难以维护。
  • 可重用性差:在多个应用程序之间共享代码和资源比较困难。
  • 安全性问题:所有的类都在同一个类路径中,这可能导致意外的访问和依赖关系。

Java模块化解决了这些问题。模块是一种新的编程单元,它可以包含类、资源和其他模块的依赖关系。模块化的代码更容易维护,更容易重用,同时也提供了更好的安全性。

模块化的基本概念

在开始使用Java模块化之前,让我们先了解一些基本概念:

1. 模块(Module)

一个模块是一个可重用的单元,它包含了一组相关的类和资源。每个模块都有一个名字,并可以声明自己的依赖关系。

2. 模块声明(Module Declaration)

一个模块声明是一个包含在module-info.java文件中的文件,它定义了一个模块的名称、依赖关系和其他特性。

3. 模块路径(Module Path)

模块路径是一组目录和JAR文件,其中包含了模块的JMOD文件和module-info.class文件。模块路径用于告诉JVM哪些模块可用。

4. 模块化 JAR 文件(Modular JAR File)

模块化JAR文件是一种特殊类型的JAR文件,它包含了一个模块的类和资源,以及module-info.class文件。

5. 自动模块(Automatic Module)

如果一个JAR文件没有module-info.class文件,它被称为自动模块。自动模块的名称基于JAR文件的文件名,并且具有一些默认的依赖关系。

6. 依赖性(Dependency)

一个模块可以声明对其他模块的依赖关系,以便在编译时和运行时使用其他模块的类和资源。

创建一个简单的模块

让我们从创建一个简单的Java模块开始,以便更好地理解模块化的概念。假设我们有一个应用程序,它有两个模块:一个模块用于处理数据库连接,另一个模块用于处理用户界面。

第一步:创建数据库模块

首先,我们创建一个数据库模块,它包含了一个简单的类DatabaseConnection

// DatabaseConnection.java
package com.example.database;public class DatabaseConnection {public void connect() {System.out.println("Connected to the database.");}
}

然后,我们为该模块创建一个module-info.java文件,声明该模块的名称:

// module-info.java
module databaseModule {
}

这个模块不依赖于其他模块,所以module-info.java文件中没有声明任何依赖关系。

第二步:创建用户界面模块

接下来,我们创建一个用户界面模块,它包含了一个简单的类UserInterface

// UserInterface.java
package com.example.ui;public class UserInterface {public void display() {System.out.println("User interface displayed.");}
}

为该模块创建一个module-info.java文件,声明该模块的名称和对数据库模块的依赖:

// module-info.java
module uiModule {requires databaseModule;
}

这个模块声明了对databaseModule的依赖,这意味着它可以使用databaseModule中的类和资源。

第三步:编译和运行模块

现在,我们可以使用Java 9编译器来编译这两个模块:

javac -d out/database databaseModule/*.java
javac -d out/ui --module-path out databaseModule/*.java uiModule/*.java

然后,我们可以运行UserInterface类来启动我们的应用程序:

java --module-path out -m uiModule/com.example.ui.UserInterface

这将会输出:

Connected to the database.
User interface displayed.

模块化的更多操作

当您在Java应用程序中使用模块化时,可以执行许多不同的操作,以更好地组织、管理和优化您的代码。以下是一些模块化的更多操作:

  1. 导出和打包模块:您可以使用exports关键字在module-info.java中声明哪些包可以被其他模块访问。这允许您控制哪些部分的代码对外可见。例如:

    module myModule {exports com.example.mypackage;
    }
    

    您还可以使用opens关键字导出包,以便其他模块可以反射地访问包中的非公开类型。

  2. 开放模块:如果您希望模块对所有其他模块开放,可以使用open关键字。这对于编写插件或扩展模块很有用。

    module myModule {open com.example.mypackage;
    }
    
  3. 命令行工具:Java 9引入了一些命令行工具,如jdeps,用于分析模块之间的依赖关系,以及jlink,用于创建自定义运行时映像。

  4. 运行时图像:您可以使用jlink命令将您的模块化应用程序与JRE一起打包成自定义运行时图像。这有助于减小应用程序的大小,因为只包括了应用程序所需的模块。

  5. 模块路径:模块路径是一个包含模块的目录或JAR文件的集合,它用于在运行时加载模块。您可以使用--module-path选项来指定模块路径。

  6. 自动模块:如果您的应用程序包含非模块化的JAR文件,Java会自动将它们转换为自动模块,以便它们可以与模块一起使用。

  7. 模块化JAR文件:您可以使用jar工具创建模块化的JAR文件,其中包含了模块描述文件(module-info.class)。

  8. 模块化库:许多常用的Java库已经进行了模块化,以便更好地与模块化应用程序集成。您可以在模块路径上指定这些库,而无需手动管理它们的依赖关系。

  9. 模块化测试:使用模块路径和--module选项,您可以在单元测试中模拟模块化环境。

  10. 版本管理:在module-info.java中可以使用requires static关键字来声明可选依赖关系,这些依赖关系只在模块可用时才会生效。

这些是模块化Java应用程序中的一些更多操作。模块化使得Java应用程序更易于维护和扩展,同时提供了更好的封装和可重用性。根据您的项目需求,您可以选择适当的操作来更好地利用模块化的优势。

模块化的最佳实践

以下是一些模块化的最佳实践:

  1. 模块命名规范:给模块取一个有意义的名字,通常使用逆域名表示法(例如:com.example.myapp)。

  2. 明确的依赖关系:在module-info.java文件中明确声明模块的依赖关系,以确保应用程序的模块之间的依赖关系清晰可见。

  3. 最小依赖原则:尽量减少模块之间的依赖关系,只依赖于真正需要的模块。

  4. 版本化的依赖关系:如果可能的话,使用版本化的依赖关系来确保模块依赖的是正确的版本。

  5. 单一责任原则:将每个模块限制为一个特定的功能或领域,以提高可维护性和可重用性。

  6. 测试和验证:确保模块之间的依赖关系和交互在编译时和运行时都能正常工作。

  7. 模块路径管理:管理模块路径以确保应用程序能够正确加载和运行。

注意事项

在编写和使用模块化的Java应用程序时,有一些重要的注意事项,以确保您的应用程序正确运行和维护。以下是一些模块化的注意事项:

  1. 模块依赖关系:仔细考虑您的模块之间的依赖关系。确保模块之间的依赖关系是明确的,避免循环依赖。使用requires语句声明依赖关系,并根据需要使用requires transitiverequires static

  2. 版本管理:了解模块之间的版本管理。Java 9引入了模块化版本的概念,允许模块依赖于特定版本的其他模块。考虑使用requires static来声明可选的、仅在特定版本下才有效的依赖关系。

  3. 模块命名:为您的模块选择合适的名称。模块名称应该唯一且易于理解。遵循Java的包命名约定,使用反向域名(例如com.example.mymodule)。

  4. 模块路径:在运行应用程序时,使用--module-path选项指定模块路径。确保正确设置模块路径,以便Java可以找到并加载您的模块。

  5. 非模块化库:如果您使用了非模块化的JAR文件,将其包装为自动模块或创建模块化的版本。非模块化库的依赖关系可能会引入复杂性。

  6. 模块化库:考虑使用已经模块化的库,以减少与模块路径和版本管理相关的问题。

  7. 运行时图像:如果您使用jlink创建自定义运行时图像,请确保包括了所有必要的模块,并排除不必要的模块,以减小应用程序的大小。

  8. 测试:编写单元测试以确保模块化应用程序的正确性。使用模块路径和--module选项来模拟模块化环境进行测试。

  9. 模块描述文件:模块描述文件(module-info.java)是模块化应用程序的关键组成部分。确保正确声明依赖关系、导出和打包模块,以及使用其他关键字来管理可见性。

  10. 模块间通信:模块之间的通信应该在依赖模块的基础上进行。不要尝试绕过模块系统的可见性控制。

  11. 跨模块访问:如果需要在模块之间共享数据或访问非公开成员,请使用opensopens...to语句,以允许受信任的模块进行反射操作。

  12. 性能和内存开销:模块化应用程序的启动时间和内存开销可能会有所增加。在部署和测试应用程序时,要考虑性能方面的因素。

  13. 迁移:如果您正在迁移现有的应用程序到模块化架构,确保逐步迁移,以减少中断和问题。

  14. 文档和培训:为开发团队提供关于模块化的文档和培训,以确保所有开发人员都理解和遵守模块化的最佳实践。

  15. 工具支持:使用Java 9及更高版本,以充分利用模块化系统和相关的工具,如jdepsjlinkjmod

这些注意事项有助于确保您的模块化Java应用程序能够正确运行

结论

Java模块化是一个强大的工具,可以帮助您更好地组织和管理代码,提高可维护性和可重用性。本文介绍了模块化的基本概念,以及如何创建和使用模块。遵循最佳实践,可以使您的Java应用程序更加健壮和可维护。希望本文对您理解Java模块化有所帮助。

作者信息

作者 : 繁依Fanyi
CSDN: https://techfanyi.blog.csdn.net
掘金:https://juejin.cn/user/4154386571867191

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/141892.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于微信小程序的美术馆预约平台设计与实现(源码+lw+部署文档+讲解等)

前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…

SLAM从入门到精通(IMU参数的读取)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 上一篇文章我们说过,对于差速轮来说,旋转的计算很多程度上依赖于thetatan(theta)这个公式来进行的。但是,我们也…

以太坊代币标准ERC20、ERC165、ERC721

两个概念 ERC(Ethereum Request for Comment) 以太坊意见征集稿EIP(Ethereum Improvement Proposals)以太坊改进提案 ERC和EIP用于使得以太坊更加完善;在ERC中提出了很多标准,用的最多的标准就是它的Token标准; 有哪些标准详细见https://eips.ethereum…

中国TO B投资,迈入第二周期

2023年,中国TOB正在愈发成熟,迈进第二个周期的趋势已经体现在融资金额上。 作者|斗斗 编辑|皮爷 出品|产业家 TOB,依旧是一级市场的大热门。 统计数据显示,截止2023年8月31日,TOB领域共发生融资事件406起,同比2022年减少…

phpstudy2016 RCE漏洞验证

文章目录 漏洞描述漏洞验证 漏洞描述 PHPStudyRCE(Remote Code Execution),也称为phpstudy_backdoor漏洞,是指PHPStudy软件中存在的一个远程代码执行漏洞。 漏洞验证 打开phpstudy2016,用bp自带的浏览器访问www目录下…

Vue3+element-plus切换标签页时数据保留问题

记录一次切换标签页缓存失效问题,注册路由时name不一致可能会导致缓存失效

Unity中Shader通道ColorMask

文章目录 [TOC](文章目录) 前言一、ColorMask是用来干什么的二、怎么做到和 Unity UI 中的 Shader 一样根据UI层级自动适配Shader中模板测试值1、借鉴Unity官方的 UI Shader 前言 Unity中Shader通道ColorMask 一、ColorMask是用来干什么的 ColorMask RGB | A | 0 | R、G、B、…

雨课堂 运动与健康 网课参考资料

整理于网络:仅用于学习交流讨论,侵删 参考文档:https://www.doc88.com/p-99629779008847.html 参考视频: 运动与健康(2021年秋网课答案 69题版本)_哔哩哔哩 | https://www.bilibili.com/video/av210112837/…

WebGL 用鼠标控制物体旋转

目录 鼠标控制物体旋转 如何实现物体旋转 示例程序(RotateObject.js) 代码详解 示例效果 鼠标控制物体旋转 有时候,WebGL程序需要让用户通过鼠标操作三维物体。这一节来分析示例程序RotateObject,该程序允许用户通过拖动&…

DT 卡通材质学习 一

渐变着色器 相交线 笔刷和卡通结合使用 修改器

计算机类软件方向适合参加的比赛

前言 博主是一名计算机专业的大三学生,在校时候参加了很多比赛和训练营,现在给大家博主参加过的几个的比赛,希望能给大一大二的学生提供一点建议。 正文 最近也有比赛的,我会从时间线上来给大家推荐一些比赛,并且给…

大屏大概是怎么个开发法(前端)

写在前面,博主是个在北京打拼的码农,从事前端工作5年了,做过十多个大大小小不同类型的项目,最近心血来潮在这儿写点东西,欢迎大家多多指教。 对于文章中出现的任何错误请大家批评指出,一定及时修改。有任何…

AutoDL云服务器的使用

目录 简介使用流程租借连接服务器输入登录指令以及密码设置服务器环境和同步文件 使用技巧查看远程主机资源上传下载数据如果上传的文件是压缩包 我的心得将大文件用百度云盘上传,小文件通过同步区域上传跨实例拷贝数据如果本实例没GPU选择其他实例 简介 使用此云服…

位移贴图的实现原理

在以前的文章中介绍过GLTF编辑器 , 编辑器可以对模型的各种材质纹理进行编辑修改,但是有一些新手用户可能对这些材质纹理不太了解,所以我收集了一些资料对这些材质纹理做一下详细的介绍,今天这篇文章主要是介绍位移贴图。 1、什么…

CMOS图像传感器——Stack Pixel(2)

在去年的时候, 就写过Sony大法的Stack Pixel CMOS图像传感器——Stack Pixel_stacked-pixel cis_沧海一升的博客-CSDN博客对索尼的2-Layer Transistor Pixel技术进行了介绍_stacked-pixel cishttps://blog.csdn.net/qq_21842097/article/details/127007460 IEDM 2021 上…

【好文推荐】openGauss 5.0.0 数据库安全——全密态探究

前言 写此文章的目的,主要是验证: openGauss 5.0.0 数据库能够实现哪种加密方式的全密态全密态数据库的特点 一、全密态介绍 全密态数据库意在解决数据全生命周期的隐私保护问题,使得系统无论在何种业务场景和环境下,数据在传…

Vue中的深度监听(Deep Watch):详细解析与实际示例

Vue中的深度监听(Deep Watch):详细解析与实际示例 Vue.js 是一款流行的前端 JavaScript 框架,其响应式系统是其核心特性之一。通过响应式系统,Vue允许开发者轻松地监听数据的变化并对其做出响应。在某些情况下&#x…

Redis的softMinEvictableIdleTimeMillis和minEvictableIdleTimeMillis参数

背景: Redis的softMinEvictableIdleTimeMillis,minEvictableIdleTimeMillis是一个令人疑惑两个参数,特别是当它和minIdle组合起来时就更难理解了,本文就来梳理下他们的之间的关系 softMinEvictableIdleTimeMillis,mi…

2023智慧云打印小程序源码多店铺开源版 +前端

智慧自助云打印系统/智慧云打印小程序源码 前端 这是一款全新的基于Thinkphp的最新自助打印系统,最新UI界面设计的云打印小程序源码

【Java 基础篇】Java网络编程实战:P2P文件共享详解

Java网络编程是现代软件开发中不可或缺的一部分,因为它允许不同计算机之间的数据传输和通信。在本篇博客中,我们将深入探讨Java中的P2P文件共享,包括什么是P2P文件共享、如何实现它以及一些相关的重要概念。 什么是P2P文件共享? …