Java模块教程

JPMS(Java平台模块系统)是Java 9中的主要增强功能。它也称为Project Jigsaw。在这个Java 9模块示例中,我们将大致了解模块,以及将来开始编写模块化代码时您的编程风格将如何变化。

目录

什么是
Java 9模块简介
如何编写模块化代码
摘要

什么是一般模块

在任何编程语言中,模块都是包含代码的(类似软件包的)工件,元数据描述了模块及其与其他模块的关系。理想情况下,从编译时一直到运行时都可以识别这些工件。通常,任何应用程序都是多个模块的组合,这些模块可以一起执行业务目标。

就应用程序架构而言,模块应代表特定的业务能力。它应具有该功能的自足能力,并且应仅公开使用模块功能的接口。要完成其任务,它可能依赖于其他模块,应明确声明其他模块。

因此,简而言之,一个模块应遵循三个核心原则:

  • 强封装

    封装意味着隐藏实现细节,这对于正确使用模块不是必需的。目的是封装的代码可以自由更改,而不会影响模块的用户。

  • 稳定的抽象

    抽象有助于使用接口(即公共API)公开模块功能。任何时候,您想更改模块代码中的业务逻辑或实现,更改对模块用户都是透明的。

  • 显式依赖

    模块也可以依赖于其他模块。这些外部依赖项必须是模块定义本身的一部分。模块之间的这些依赖关系通常表示为图形。在应用程序级别查看该图后,您将对应用程序的体系结构有更好的了解。

Java 9模块简介

在Java 9之前,您已经具有“  ”来根据业务功能对相关类进行分组。与包一起,您具有“ 访问修饰符 ”来控制对其他类或包可见的内容以及对其他类或包隐藏的内容。到目前为止,它一直运行良好。Java对封装和抽象有强大的支持。

但是,显式依赖关系是事情开始崩溃的地方。在Java中,依赖项是使用’ import ‘语句声明的;但严格来说,它们是“编译时”构造。一旦代码被编译,就没有任何机制可以清楚地说明其运行时依赖性。实际上,Java运行时依赖项解析是一个有很多问题的领域,因此已经创建了专用工具来解决此问题,例如gradlemaven。同样,很少有框架开始捆绑其完整的运行时依赖关系,例如Spring Boot项目。

使用新的Java 9模块,我们将具有更好的功能来编写结构良好的应用程序。此增强功能分为两个区域:

  1. 模块化JDK本身。
  2. 提供一个模块系统供其他应用程序使用。
Java 9模块系统具有一个“ java.base ”模块。它被称为基本模块。它是一个独立模块,不依赖于任何其他模块。默认情况下,所有其他模块都依赖于“ java.base ”。

在Java 9中,模块可帮助您封装程序包和管理依赖项。所以通常

  • 类是字段和方法的容器
  • 包是类和接口的容器
  • 模块是包装的容器

如果您不知道要查找的特定内容,您将不会感到普通代码和模块化代码之间有任何重大差异。例如

  1. 模块通常只是一个jar文件,该module-info.class文件的根目录。
  2. 要使用模块,请将jar文件(modulepath而不是)包含在内classpath。添加到类路径的模块化jar文件是普通的jar文件,该module-info.class文件将被忽略。

如何编写模块化代码

阅读以上所有概念后,让我们看看如何在现实中编写模块化代码。我使用Netbeans IDE是因为它具有对Java 9的良好早期支持(截至今天)。

创建Java模块化项目

创建新的模块化项目。我已经创建了name JavaAppOne

创建Java模块化项目
创建Java模块化项目
创建Java模块化项目-步骤2
创建Java模块化项目–步骤2

创建Java模块

现在,在此项目中添加一个或两个模块。

创建新模块
创建新模块

我添加了两个模块helloworldtest。让我们看看他们的代码和项目结构。

Java 9模块项目结构
Java 9模块项目结构

/helloworld/module-info.java

module helloworld {
}

HelloWorldApp.java

package com.how2codex.demo;

public class HelloWorldApp {
    public static void sayHello() {
        System.out.println("Hello from HelloWorldApp");
    }
}

/test/module-info.java

module test {
}

TestApp.java

package com.test;

public class TestApp {
    public static void main(String[] args) {
        //some code
    }
}

到目前为止,模块是独立的。现在假设,我们要HelloWorldApp.sayHello()TestApp类中使用method 。如果您尝试使用该类而不导入模块,则会收到编译时错误“包com.how2codex.demo不可见”

导出包和导入模块

为了能够导入HelloWorldApp,您必须首先从helloworld模块中导出“ com.how2codex.demo”包,然后helloworldtest模块中包含模块。

module helloworld {
    exports com.how2codex.demo;
}

module test {
    requires helloworld;
}

在上面的代码中,requires关键字表示依赖关系,exports关键字标识可以导出到其他模块的程序包。仅当显式导出包时,才能从其他模块访问它。默认情况下,无法从其他模块访问模块中未导出的软件包。

现在您将可以在HelloWorldApp类内部使用TestApp类。

package com.test;

import com.how2codex.demo.HelloWorldApp;

public class TestApp {
    public static void main(String[] args) {
        HelloWorldApp.sayHello();
    }
}

Output:

Hello from HelloWorldApp

让我们来看一下模块图。

模块图
模块图
从Java 9开始,仅public意味着public该模块内的所有其他软件包。仅当public导出包含该类型的包时,其他模块才能使用它。

摘要

模块化应用程序具有许多优点,当您遇到具有非模块化代码库的应用程序时,您会更加欣赏。您一定听过诸如“ 意大利面条建筑 ”或“ 凌乱的整体建筑 ”之类的术语。模块化不是灵丹妙药,但它是一种体系结构原理,如果正确应用,可以在很大程度上防止这些问题。

借助JPMS,Java已迈出了一大步,成为了模块化语言。决定是对还是错,只有时间会证明一切。第三方库和框架如何适应和使用模块系统将会很有趣。以及它如何影响开发工作,我们每天都在做。

学习愉快!

saigon has written 1440 articles

Leave a Reply