java9新功能-模块系统

2024-05-28  本文已影响0人  shark没有辣椒

Java 9 最大的变化之一是引入了模块系统(Jigsaw 项目)。

模块是代码和数据的封装体。模块的代码被组织成多个包,每个包中包含Java类和接口;模块的数据则包括资源文件和其他静态信息。

模块系统的目标

更好的封装性

模块化系统允许开发者显式地定义哪些部分的代码对外可见,哪些部分是内部实现细节。通过 module-info.java 文件,模块可以声明哪些包是公开的,哪些包是隐藏的。这种封装性提高了代码的安全性和可维护性。

可靠的配置

模块化系统提供了一个更可靠的方式来定义模块之间的依赖关系。在 module-info.java 文件中,模块可以声明它们需要哪些其他模块,从而在编译时和运行时确保所有必要的依赖都存在。这避免了类路径下可能存在的版本冲突和缺失依赖的问题。

强制性服务加载

模块化系统允许模块声明和使用服务,服务提供者可以通过 provides 和 uses 关键字在 module-info.java 文件中进行声明,从而实现模块之间的解耦和动态加载。

更小的运行时环境

通过模块化系统,开发者可以创建包含最小运行时环境的定制 JRE。这样可以减少应用的内存占用和启动时间,特别适合于容器化和微服务架构。

示例

我们新建一个maven项目,有moduleA和moduleB两个模块。
在moduleA中,我们定义com.example.student和com.example.teacher两个包,然后分别创建Student和Teacher两个类。

package com.example.teacher;

public class Teacher {
    public void teach() {
        System.out.println("teach");
    }
}
package com.example.student;

public class Student {
    public void study() {
        System.out.println("study");
    }
}

然后在moduleA的src/main/java目录下创建module-info.java,通过exports com.example.student声明com.example.student包是公开的,可以被其他模块访问。只有被导出的包中的公共类和接口才能被其他模块使用。

module moduleA {
    exports com.example.student;
}

然后在moduleB的src/main/java目录下创建module-info.java,通过requires moduleA声明当前模块依赖于moduleA,这会让编译器和运行时系统知道当前模块需要依赖的模块,以确保这些模块在编译和运行时都可用。

module moduleB {
    requires moduleA;
}

然后我们在moduleB中新建Test类

package com.example.test;

import com.example.student.Student;

public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        student.study();
    }
}

执行main方法,命令行会打印study,但是在Test类中,我们无法引用Teacher类,因为teacher包没有被exports声明公开。

这是项目的整体结构,我们可以看到在Test类中无法引入Teacher类。


图1

下面贴出其它代码
moduleA的pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>module-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>moduleA</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>17</release>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

moduleB的pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>module-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>moduleB</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>moduleA</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>17</release>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

项目根目录pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>module-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>moduleA</module>
        <module>moduleB</module>
    </modules>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

总结

通过这个简单的示例,展示了 moduleA 和 moduleB 两个模块是如何相互依赖和交互的。这样的设计展示了 Java 9 模块化系统如何增强代码的组织和管理,提升软件系统的可维护性和安全性。

上一篇 下一篇

猜你喜欢

热点阅读