Java - 模块系统
Java模块系统简介
你好,有抱负的Java程序员!今天,我们将开始一段激动人心的旅程,深入了解Java的模块系统。作为你友好的邻居计算机科学老师,我将一步一步地引导你了解这个迷人的话题。如果你是编程新手,请不要担心——我们将从基础开始,一起逐步学习!
什么是模块?
让我们从一个简单的类比开始。想象一下你在建造一个乐高城堡。每一个乐高积木代表一段代码,而说明书告诉你如何将它们组合在一起。在Java中,一个模块就像是你城堡中预先构建的部分——它是一组相关代码的集合,共同执行特定的功能。
在技术术语中,Java中的一个模块是一个自包含的代码单元,包括:
- 类和接口
- 资源(如图片或配置文件)
- 明确定义了它需要从其他模块获取的内容
- 声明了它提供给其他模块的内容
将其视为一个组织良好的工具箱,里面的每一样东西都有其位置和用途。
Java模块系统的特性
Java模块系统,在Java 9中引入,带来了一些令人兴奋的特性。让我们一一探索它们:
1. 强封装
记得你小时候有一个秘密盒子来存放你的宝藏吗?模块的工作方式类似。它们允许你决定你的代码的哪些部分对他人可见,哪些部分是你的“秘密宝藏”。
module com.myapp.secretbox {
exports com.myapp.secretbox.api;
}
在这个例子中,只有com.myapp.secretbox.api
包中的类对其他模块可见。其他所有内容都被隐藏了!
2. 可靠的配置
模块明确地声明了它们需要从其他模块获取的内容。这就像在去杂货店之前创建一个购物清单——你知道你确切需要什么,而且不会忘记任何东西!
module com.myapp.kitchen {
requires com.myapp.fridge;
requires com.myapp.stove;
}
在这里,我们的kitchen
模块表示它需要fridge
和stove
模块才能正常工作。
3. 改进的性能
有了模块,Java可以更智能地只加载它需要的代码。这就像只打包你实际上会穿的衣物去旅行,而不是你的整个衣橱!
声明一个模块
现在,让我们卷起袖子创建我们的第一个模块。我们首先在我们的源代码目录的根目录中创建一个名为module-info.java
的文件。
module com.myapp.greetings {
exports com.myapp.greetings.api;
}
这个简单的声明创建了一个名为com.myapp.greetings
的模块,并使com.myapp.greetings.api
包对其他模块可用。
添加依赖模块
有时,我们的模块可能需要使用其他模块中的代码。我们可以使用requires
关键字指定这些依赖。
module com.myapp.greetings {
requires com.myapp.translations;
exports com.myapp.greetings.api;
}
在这个例子中,我们的greetings
模块需要translations
模块才能正确工作。
添加可选模块
如果我们有一个模块是很好,但不是绝对必要的呢?这就是可选模块派上用场的地方!
module com.myapp.greetings {
requires com.myapp.translations;
requires static com.myapp.fancyfonts;
exports com.myapp.greetings.api;
}
static
关键字告诉Java,fancyfonts
模块是可选的。我们的greetings
模块即使没有它也可以工作,但如果它可用,可以使用fancyfonts
。
添加传递模块
有时,我们希望将我们的依赖传递给依赖我们的模块。我们可以使用transitive
关键字来实现这一点。
module com.myapp.greetings {
requires transitive com.myapp.translations;
exports com.myapp.greetings.api;
}
现在,任何需要com.myapp.greetings
的模块都将自动获得对com.myapp.translations
的访问权限。
导出公共类
当我们想要使某些包对其他模块可用时,我们使用exports
关键字。
module com.myapp.greetings {
exports com.myapp.greetings.api;
exports com.myapp.greetings.utils to com.myapp.testing;
}
在这个例子中,我们将api
包提供给所有模块,但utils
包只对com.myapp.testing
模块可用。
允许反射
有时,我们需要允许其他模块对我们的类使用反射。我们可以使用opens
关键字来实现。
module com.myapp.greetings {
exports com.myapp.greetings.api;
opens com.myapp.greetings.internal to com.myapp.testing;
}
这允许com.myapp.testing
模块对com.myapp.greetings.internal
包中的类使用反射。
创建和使用Java模块
现在我们已经介绍了基础知识,让我们把它放在一起创建一个简单的模块化应用程序。我们将创建两个模块:com.myapp.greetings
和com.myapp.main
。
首先,让我们创建com.myapp.greetings
模块:
// module-info.java
module com.myapp.greetings {
exports com.myapp.greetings;
}
// com/myapp/greetings/Greeter.java
package com.myapp.greetings;
public class Greeter {
public static String greet(String name) {
return "Hello, " + name + "!";
}
}
现在,让我们创建一个使用我们的greetings
模块的com.myapp.main
模块:
// module-info.java
module com.myapp.main {
requires com.myapp.greetings;
}
// com/myapp/main/Main.java
package com.myapp.main;
import com.myapp.greetings.Greeter;
public class Main {
public static void main(String[] args) {
System.out.println(Greeter.greet("Java Modules"));
}
}
要编译和运行这个模块化应用程序,我们使用以下命令:
javac -d mods --module-source-path src $(find src -name "*.java")
java --module-path mods -m com.myapp.main/com.myapp.main.Main
瞧!你刚刚创建并运行了你的第一个模块化Java应用程序。
结论
恭喜你完成了对Java模块系统的介绍!我们已经介绍了很多内容,从理解模块是什么到在真实应用程序中创建和使用它们。请记住,就像学习骑自行车一样,掌握模块需要练习。不要害怕实验和犯错误——这是我们学习的最佳方式!
在你继续Java之旅时,你会发现模块帮助你创建更组织化、更安全、更高效的应用程序。它们就像是将你的编程技能从好提升到优秀的秘密成分。
继续编码,继续学习,最重要的是,玩得开心!下次见,愉快的模块化!
Credits: Image by storyset