java系统介绍_Java模块系统详细介绍

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的同时,也能紧跟潮流技术的发展!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值