动力节点旗下在线教育品牌  |  咨询热线:400-8080-105 学Java全栈,上蛙课网
首页 > 文章

Java模块系统详细介绍

07-20 17:56 302浏览
举报 T字号
  • 大字
  • 中字
  • 小字

Java 和相关生态在不断丰富的同时也越来越暴露出一些问题,为了解决这些问题,Java 9中的java模块系统应运而生。Java 9之前,都是Java的顶级代码组织元素。从Java 9开始发生了一些变化:软件包上方是模块,它可以将相关的软件包收集在一起。

Java平台模块系统(JPMS)是代码级结构,因此不会改变我们将Java打包到JAR文件中的事实。最终,所有内容仍然捆绑在JAR文件中。通过合并module-info.java文件,模块系统添加了JAR可以使用的新的更高级别的描述符。大型应用程序和组织将利用模块来更好地组织代码。本质上讲,模块(module)的概念,其实就是package外再裹一层,也就是说,用模块来管理各个package,通过声明某个package暴露,不声明默认就是隐藏。因此,模块化使得代码组织上更安全,因为它可以指定哪些部分可以暴露,哪些部分隐藏。但是每个人都将使用模块,因为JDK及其类现已模块化。

JPMS是Jigsaw项目的成果,该项目的目标是实现以下目标:

1.使开发人员更容易组织大型应用程序和库

2.改善平台和JDK本身的结构和安全性

3.提高应用程序性能

4.更好地处理较小设备的平台分解

值得注意的是,JPMS是SE(标准版)功能,因此从头开始影响Java的各个方面。话虽如此,更改的目的是使大多数代码从Java 8迁移到Java 9时无需修改即可运行。对此有一些例外,我们将在本概述的后面部分对其进行说明。

模块背后的主要思想是允许收集模块可见的相关程序包,同时向模块的外部使用者隐藏元素。换句话说,模块允许另一级别的封装。

类路径和模块路径:到目前为止,在Java中,类路径一直是正在运行的应用程序可用内容的底线。尽管类路径用于此目的并已广为人知,但它最终是一个大的,没有差别的存储桶,所有依赖项都放置在其中。模块路径在类路径上方添加一个级别。它充当程序包的容器,并确定应用程序可以使用哪些程序包。

JDK本身现在由模块组成JDK安装目录中有一个/lib目录。在该目录内是一个src.zip文件。将其解压缩到/src目录中。在/src目录中查找,然后导航到/java.base目录。在那里找到module-info.java文件打开它。

在顶部的Javadoc注释之后,将找到一个名为module java.base的部分,你会看到许多Java熟悉的软件包(如java.io)都是从java.base模块中导出的。这是将软件包收集在一起的模块的本质。

另一exports是requires指令。针对模块运行Java编译器时,可以通过类似于类路径的方式指定模块路径。

让我们看一下模块化Java项目的结构。我们将制作一个包含两个模块的小程序,一个模块提供一个依赖关系,另一个模块使用该依赖关系并导出可执行的主类。在文件系统上方便的位置创建一个新目录。叫它/com.javaworld.mod1。按照约定,Java模块位于与模块同名的目录中。在此目录中,创建一个module-info.java文件。在内部,添加下面中的内容

com.javaworld.mod1 / module-info.java

module com.javaworld.mod1 {

  exports com.javaworld.package1;

}

注意,模块和导出的包是不同的名称。我们正在定义一个导出包的模块。

现在,在包含该module-info.java文件的目录内的此路径上创建一个文件/com.javaworld.mod1/com/javaworld/package1。命名文件  Name.java。将下面的内容放入其中

Name.java

package com.javaworld.package1;

 

public class Name {

  public String getIt() {

    return "Java World";

  }

}

上面的代码将成为我们所依赖的类,包和模块。然后,创建另一个与之平行的目录/com.javaworld.mod1 并调用它/com.javaworld.mod2。在这个目录中,创建一个module-info.java模块定义,该定义将导入我们已经创建的模块,如下面的代码所示。

com.javaworld.mod2 / module-info.java

 

module com.javaworld.mod2 {

  requires com.javaworld.mod1;

}

这段代码的意义是不言自明的。它定义了com.javaworld.mod2模块并要求com.javaworld.mod1。

/com.javaworld.mod2目录内,创建一个类路径,如下所示:/com.javaworld.mod2/com/javaworld/package2。在其中添加一个名为的文件Hello.java,其中包含下面的代码。

Hello.java

package com.javaworld.package2;

 

import com.javaworld.package1.Name;

 

public class Hello {

  public static void main(String[] args) {

    Name name = new Name();

    System.out.println("Hello " + name.getIt());

  }

}

在上面的代码中,首先定义包,然后导入com.javawolrd.package1.Name类。,这些元素的功能与以往一样。这些模块已更改了如何在文件结构级别(而不是代码级别)使软件包可用。同样,我们应该熟悉代码本身它只是创建一个类并在其上调用一个方法来创建经典的“ hello world”示例。

运行模块化Java示例

第一步是创建目录以接收编译器的输出。/target在项目的根目录创建一个目录。在内部,为每个模块创建一个目录:/target/com.javaworld.mod1和/target/com.javaworld.mod2。

然后是编译依赖性模块,并将其输出到/target目录。在项目的根目录下,输入:

Javac-d target/com.javaworld.mod1com.javaworld.mod1/module-info.java com.javaworld.mod1/com/javaworld/package1/Name.java

这将导致源及其模块信息一起构建。

接下来是生成从属模块。输入下面的命令。

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

让我们详细看一下上面的命令。它将module-path参数引入javac。这使我们能够以与--class-path开关类似的方式定义模块路径。

执行模块主类

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

--module-path开关告诉Java使用/target目录作为模块根目录,即在哪里搜索模块。该-m开关是告诉我们Java主类是什么。注意,我们在其全称的类名前加上了其模块。最后我们将看到输出Hello Java World。

鉴于先前的代码库对模块路径一无所知,你可能想知道如何在后Java 9世界中运行以模块前版本编写的Java程序。答案是Java 9设计为向后兼容。但是,新的模块系统发生了很大的变化,我们可能会遇到问题,尤其是在大型代码库中。

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

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

对于依赖项引起的错误,可以希望所依赖的软件包具有更新的Java 9兼容版本。如果没有,只能寻找替代品。

下面是一个常见的错误:

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

这是Java抱怨找不到一个类,因为它已迁移到一个模块,无法查看使用的代码。有几个不同的复杂性和永久性的解决方案,描述在这里。同样,如果发现具有依赖项的此类错误,请检查项目。他们可能具有Java 9构建供我们使用。

JPMS是一个相当大的变化,需要时间的酝酿和发酵。相信会在未来的项目中得到普遍采用。由于Java 8是长期支持版本,所以如果没有刚需的话不需要立刻采用JPMS。话虽如此,从长远来看,较旧的项目将需要迁移,而新的项目将需要智能地使用模块,这也是java发展的一个必然趋势。想了解更多最新的java前沿技术,可以观看本站的专业java视频课程哦,让我们在学习java的同时,也能紧跟潮流技术的发展!

0人推荐
共同学习,写下你的评论
0条评论
代码小兵1258
程序员代码小兵1258

4篇文章贡献24871字

作者相关文章更多>

推荐相关文章更多>

Java数据结构

HelloWorld10-31 08:24

浅谈MySQL中SQL优化的常用方法

军哥08-12 23:29

五分钟读懂UML类图

江湖人称小李白12-10 10:41

MyBatis开发框架的四大核心

IT逐梦者08-17 21:43

一次搞定continue,break和return

HelloWorld11-06 11:19

发评论

举报

0/150

取消