百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Java模块系统新特性快速上手指南(深入理解java模块系统)

toyiye 2024-09-01 05:33 4 浏览 0 评论



0.导引

Java发展的越来越无所不能了,从Java 9+开始而引入的平台模块系统,就是一个很大的新特性,使组织代码变得更容易,也更易于功能解耦化和微型化。本文是一个使用Java模块的简短快速上手指南。

在Java 9之前,Java的顶级代码组织元素一直是包。从Java 9开始变了:在包package的上面是模块module。模块将相关的包收集聚合在一起。

Java平台模块系统(JPMS,Java Platform Module System)是一种代码级结构,其不会改变将Java打包到JAR文件中的事实。本质上讲,所有内容仍然打包在JAR文件中。模块系统通过结合 module-info.java文件,添加了jar可以使用的新的高级描述符。

大型应用程序和组织机构,可以利用模块化来更好地组织代码。其实现在每个人都在使用着模块,因为JDK及其类现在已经模块化了。

1.为什么Java需要模块

JPMS是Jigsaw工程的成果,该工程的目标如下:

  • l 使开发人员更容易组织大型应用程序和库;
  • l 改进平台和JDK本身的结构和安全性;
  • l 提高应用程序性能;
  • l 对于较小的设备,更好地处理平台的分解面。

值得注意的是,JPMS是一个SE(标准版)特性,因此会从头影响Java的各个方面。尽管如此,这种结构改变后的设计,当在从Java 8迁移到Java 9时,最大程度的允许功能代码无需修改即可运行。这里有一些例外,我们将在稍后的概述中进行说明。

模块背后的主要思想是允许相关包的集合对模块是可见的,而对模块的外部使用者隐藏一些要素。换句话说,模块是允许另一种级别的封装。

2.类路径和模块路径

到目前为止,在Java中,类路径一直是运行着的程序的可用内容的底线。尽管类路径服务于此目的,并且很容易理解,但它最终将是一个大的、无差异的桶,所有依赖项都被放置在其中。

模块路径在类路径之上添加了一个级别。它充当包的容器,并决定哪些包对应用程序可用。

3.JDK中的模块

JDK本身现在是由模块组成的。让我们从JPMS的细节开始。

如果您的系统上有JDK,那么您也有源代码。如果您不熟悉JDK以及如何获得它,请参阅@牛旦IT课堂的这篇文章:JDK 、JRE 与JVM之间的关系及区别

在JDK安装目录中有一个/lib目录。在该目录中有一个src.zip文件。将其解压缩到/src目录中。

查看/src目录,并导航到/java.base目录。在那里您将找到module-info.java文件,然后打开它。

在头部的Javadoc注释之后,您会发现一个命名为module java.base的部分,其随后有一系列exports行。这里我们不详细讨论格式,因为它相当深奥。详情请点击这里的连接(https://blog.joda.org/2017/04/java-se-9-jpms-module-naming.html)——有机会我再详解之。

您可以看到许多熟悉的Java包,比如java.io,是从java.base模块导出的。这是集合或汇聚相关包的模块本质。

exports的另一面是requires指令。这允许被定义的模块被引入(需要)到某个模块。

在对模块运行Java编译器时,可以类似于类路径的方式指定模块路径。这样就可以解决依赖问题。

4.创建模块化Java项目

让我们来看看模块化Java项目是如何构建的。我打算创建一个有两个模块的小程序,一个提供依赖项,另一个使用依赖项并导出一个可执行的主类。

在文件系统中某地方创建一个新目录(模块名),叫它/com.inewday.mod1。按照约定,Java模块位于与模块同名的目录中。


现在,在这个目录中,创建一个module-info.java文件。在其中添加清单1中的内容。

清单 1: com.inewday.mod1/module-info.java

module com.inewday.mod1 {
  exports com.inewday.package1;
}

请注意,模块和它导出的包是不同的名称。此处我定义了导出包的模块。

现在在这个路径上创建一个文件,在目录中包含module-info.java文件:/com.inewday.mod1/com/inewday/package1。将文件命名为Name.java。将清单2的内容写入其中。

清单2 Name.java

package com.inewday.package1;
 
public class Name {
  public String getIt() {
    return "Java Module World";
  }
}

清单2将成为我们所依赖的类、包和模块。

现在我来创建另一个与/com.inewday.mod1平行的目录,并叫做/com.inewday.mod2。在这个目录中,我来创建一个module-info.java模块定义,它导入我已经创建的模块,如清单3所示。

清单 3: com.inewday.mod2/module-info.java

module com.inewday.mod2 {
  requires com.javaworld.mod1;
}

清单3不言而喻,它定义了com.inewday.mod2模块,并引入/需要com.inewday.mod1。

在/com.inewday.mod2目录下,创建类路径如下:/com.inewday.mod2/com/inewday/package2。

现在在里面添加一个名为Hello.java的文件。使用清单4中提供的代码。

清单 4 Hello.java

package com.inewday.package2;
 
import com.inewday.package1.Name;
 
public class Hello {
  public static void main(String[] args) {
    Name name = new Name();
    System.out.println("Hello " + name.getIt());
  }
}

在清单4中,我们从定义包开始,然后导入com.inewday.package1.Name类。请注意,这些元素一如既往地发挥作用。这些模块已经改变了包在文件结构层(而不是代码层)可用的方式。

类似地,您应该对代码本身很熟悉。它只是简单地创建一个类并对其调用一个方法来创建一个经典的“hello world”雷同示例。

5.运行模块化Java示例



第1步:创建接收编译器输出的目录。在项目的根目录中创建一个名为/target的目录。在其内部,分别为每个模块创建一个目录:/target/com.inewday.mod1和/target/com.inewday.mod2。

第2步:编译依赖项模块,并将其输出到/target目录。在项目的根目录中,输入清单5中的命令。(假设已经安装了JDK。)

清单5:构建模块1

javac -d target/com.inewday.mod1 com.inewday.mod1/module-info.java com.inewday.mod1/com/inewday/package1/Name.java

这将导致源代码随其模块信息一起被构建。

第3步:生成依赖模块。输入清单6中所示的命令。

清单6:构建模块2

javac --module-path target -d target/com.inewday.mod2 com.inewday.mod2/module-info.java com.inewday.mod2/com/inewday/package2/Hello.java

请详细看看清单6。它将module-path参数引入到javac。这允许我们以类似于--class-path开关的方式定义模块路径。在本例中,我将传入target目录,因为清单5在该目录中输出模块1。

接下来,清单6(通过-d开关)定义了模块2的输出目录。最后给出了编译的实际主题,即模块2中包含的module-info.java文件和类。

为了运行程序,使用清单7中所示的命令。

清单7:执行模块主类

java --module-path target -m com.inewday.mod2/com.inewday.package2.Hello

--module-path开关告诉Java使用/target目录作为模块根目录,也就是说,在哪里搜索模块。-m开关是告诉Java主类在什么地方。注意,我们在完全限定类名的前面加上它的模块。

您将看到输出Hello Java Module World

6.向后兼容性

您可能很想知道如何在后Java 9世界中运行用模块化前编写的Java程序,因为以前的代码库对模块路径一无所知。答案是Java 9被设计为向后兼容,即以前代码依然可以运行在9及以后的版本中。但是,新的模块系统是一个巨大的变化,您可能会遇到问题,特别是在大型代码库中。

在Java 9上运行9以前的代码库时,您可能会遇到两种错误:一种源自您的代码库,另一种源自您的依赖。

对于源于代码库的错误,这个命令可能会有所帮助:jdeps。当指向一个类或目录时,该命令将扫描存在哪些依赖项,以及这些依赖项依赖的模块。

对于源于依赖关系的错误,您可寄希望您所依赖的包将会有更新的Java 9兼容构建版本。如果没有,你可能不得不寻找其他选择。

一个常见的错误是这样的:

How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

这是Java抱怨找不到某个类,因为它已经迁移到一个模块,而对使用方(消费代码)不可见。这里(https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception-in-j) 描述了几种具有不同复杂性和持久性的解决方案。

同样,如果在依赖项中发现此类错误,请进行项目检查。它们可能有Java 9构建版本供您使用。

JPMS是一个相当彻底的改变,需要时间来适应。幸运的是,并不着急,因为Java 8是一个长期支持版本。

也就是说,从长远来看,旧的项目将需要迁移,而新的项目将需要明智地使用模块,以期能够利用一些模块应允的好处。

7.小结

本文简要介绍了Java中的模块系统的相关技术知识,并做了实例性演示实战操作,动手练一把,基本就能窥得JPMS的总体特性了,后续有机会再深入讲解相关技术细节。

本篇就到这里了,关注一下,分享出去吧,谢谢.


相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码