网站首页 > java教程 正文
模块化是 Java 9 一个非常重要的特性,终于有时间整理一下这方面的内容了。
模块化是软件工程中非常重要的一个概念。把独立的功能封装成模块,并提供接口供外部使用是我们在开发中努力实现的目标。模块化有很多好处:
代码内聚,容易维护;
能够有效降低复杂度;
能提供更好的伸缩性和扩展性。
Java 9 的 Jigsaw 项目致力于为 Java 9 带来平台级的模块化系统。这个项目从 2008 年就已经开始,由于很多原因一直没有发布。现在,Jigsaw 涵盖了 6 个 JEP,终于作为 Java 9 的一部分发布出来。
从整体到模块
Java 一直坚持向后兼容,每更新一个版本,都变得更大更复杂。在过去的 JDK 版本中,没有强制要求模块化,使得 Java 平台和 JDK 越来越让人纠结。即便只是一个小小的 hello world,也需要加载几乎所有的 API。Jigsaw 项目致力于把 Java 平台和 JDK 分解成更小更有组织的模块。用户可以使用模块来构建软件,并且不需要包含所有的 API。
这项工作并不容易,Oracle 的 Java 平台组首席架构师 Mark Reinhold 曾经说过:
JDK代码库在API和实现级别上都是相互关联的,多年来主要以单片软件系统的方式构建。我们花了相当多的努力消除或至少简化了尽可能多的API和实现依赖关系,以便平台和它的实现可以作为一组相互依赖的模块来呈现,但是一些特别棘手的情况仍然存在。我们希望尽可能多地保持与先前版本的兼容性,特别是对于现有的基于类路径的应用程序,同时在可能的情况下,对于由模块组成的应用程序也是如此。
所有 Java 9 模块都在 $JAVA_HOME/jmods 目录下面。每个模块都具有暴露给其他模块的接口。这些模块互相依赖,并通过导出的包进行交互。 开发人员可以编译、打包、部署和执行仅由所选模块组成的应用程序,而无需其他任何操作。
如何使用模块
下面我们把自己的 Java 代码也进行模块化。新建两个简单的模块:
com.timeteller.clock:包含SpeakingClock的模块,用于将当前时间打印到stdout的简单类;
com.timeteller.main:使用com.timeteller.clock模块提供的功能的模块。
整个项目结构如下所示:
├── com.timeteller.clock │ ├── com │ │ └── timeteller │ │ └── clock │ │ └── SpeakingClock.java │ └── module-info.java └── com.timeteller.main ├── com │ └── timeteller │ └── main │ └── Main.java └── module-info.java
在 main 函数中调用方法与之前并无多少不同。
public static void main (String[] args) { SpeakingClock clock = new SpeakingClock(); clock.tellTheTime(); // displays the time to stdout. }
Java 9 平台级模块化系统最重要的部分在 module-info.java 中,这个文件定义了模块和元数据。内容如下所示。一个文件定义了 com.timeteller.clock 模块,并导出了 com.timeteller.clock 包;另一个文件定义了 com.timeteller.main 模块,并引用了 com.timeteller.clock 模块。
module com.timeteller.clock { exports com.timeteller.clock; }
module com.timeteller.main { requires com.timeteller.clock; }
module-info.java 的配置比较简单,可以看到:
模块描述符文件放置在模块的根文件夹中;
每个模块都有一个唯一的名称;
模块描述符定义从模块导出的包以及它们需要哪些模块;
模块中的包如果没有导出,它的作用域就仅限于当前模块中,其他模块无法使用。这一特性使得 Java 9 中的 public 含义有所变化,模块中声明为 public 的类不再是可以随意访问的,只有导出以后才能从模块外访问到。基于这个特性,可以有效地隐藏模块内的 API。
编译 Java 程序
编译时可以这样打包:
$ mkdir -p jars $ mkdir -p build/classes/com.timeteller.clock $ javac -d build/classes/com.timeteller.clock/ com.timeteller.clock/module-info.java com.timeteller.clock/com/timeteller/clock/SpeakingClock.java $ jar -c -f jars/clock.jar -C build/classes/com.timeteller.clock/ . $ mkdir -p build/classes/com.timeteller.main $ javac -d build/classes/com.timeteller.main/ --module-path=jars com.timeteller.main/module-info.java com.timeteller.main/com/timeteller/main/Main.java $ jar -c -f jars/timeTeller.jar --main-class com.timeteller.main.Main -C build/classes/com.timeteller.main .
我们必须告诉编译器模块的路径(modulepath),编译器才能准确编译。模块路径的概念与 classpath 的概念非常相似。当我们构建 com.timeteller.main 模块时,需要在它的模块路径上放一个带有 com.timeteller.clock 的 jar。否则编译器找不到必需的代码并会导致编译错误:
$ javac -d build/classes/com.timeteller.main/ com.timeteller.main/module-info.java com.timeteller.main/com/timeteller/main/Main.java com.timeteller.main/module-info.java:2: error: module not found: com.timeteller.clock requires com.timeteller.clock;
这里编译后创建的 jar 也是模块化,模块的 jar 与常规的 jar 基本一样,除了里面包括 module-info.class 文件。Java 9 即将到来,让我们一起期待吧。
分享学习笔记和技术总结,内容涉及 Java 进阶、架构设计、前沿技术、算法与数据结构、数据库、中间件等多个领域。关注作者第一时间获取最新内容,公众号同名(阅读体验更佳)。
猜你喜欢
- 2024-09-11 Java 9最终发布可能会推迟8周,到9月21日
- 2024-09-11 JAVA9模块化详解(一)——模块化的定义
- 2024-09-11 java 9 更新内容整理(java基础知识点整理)
- 2024-09-11 轻松上手Java 9模块化开发核心原则与实践
- 2024-09-11 Java 9 揭秘-模块化系统(二)(java9安装教程)
- 2024-09-11 Java9系列第8篇-Module模块化编程
- 2024-09-11 Java 9揭秘-模块依赖(十二)(java9模块化为啥没大规模使用)
- 2024-09-11 Java 9揭秘-模块依赖(七)(java9是什么版本)
- 2024-09-11 Java9新特性Jigsaw和Jshell(java9 模块化 系统)
- 2024-09-11 Java9新特性中的模块化到底是什么
你 发表评论:
欢迎- 最近发表
-
- Java常量定义防暴指南:从"杀马特"到"高富帅"的华丽转身
- Java接口设计原则与实践:优雅编程的艺术
- java 包管理、访问修饰符、static/final关键字
- Java工程师的代码规范与最佳实践:优雅代码的艺术
- 编写一个java程序(编写一个Java程序计算并输出1到n的阶乘)
- Mycat的搭建以及配置与启动(mycat部署)
- Weblogic 安装 -“不是有效的 JDK Java 主目录”解决办法
- SpringBoot打包部署解析:jar包的生成和结构
- 《Servlet》第05节:创建第一个Servlet程序(HelloSevlet)
- 你认为最简单的单例模式,东西还挺多
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)