下面是一个详细的教程,涵盖如何将多个 Java 文件组织成包、引入包以及如何打包成 JAR 文件的过程。
1. 创建 Java 包
1.1 目录结构
假设我们要创建一个名为 com.example.myapp 的包,目录结构如下:
[!NOTE] 一般包名就是目录结构名。因此,我们运行或者编译包时一般都是在目录根结构下运行命令,比如
com.example.myapp这个包是根据myapp/src/com/example/myapp目录下命名的,我们就要在src根目录下运行命令
myapp/
│
├── src/
│ └── com/
│ └── example/
│ └── myapp/
│ ├── HelloWorld.java
│ └── Utils.java
└── bin/
1.2 编写 Java 文件
HelloWorld. java:
package com.example.myapp;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
Utils.printMessage("This is a message from Utils.");
}
}
Utils. java:
package com.example.myapp;
public class Utils {
public static void printMessage(String message) {
System.out.println(message);
}
}
2. 编译 Java 文件
- 打开终端,导航到
src目录:cd path/to/myapp/src - 使用
javac编译 Java 文件:javac com/example/myapp/*.java -d ../bin这里
-d ../bin表示将编译生成的.class文件放到bin目录下。
3. 运行 Java 程序
- 确保你在
bin目录中:cd ../bin - 运行程序:
java com.example.myapp.HelloWorld
4. 创建 JAR 文件
- 仍然在
bin目录中,使用jar命令创建 JAR 文件:jar cvf myapp.jar com/example/myapp/*.class这里
c表示创建,v表示详细输出,f表示指定 JAR 文件名。 - 确认 JAR 文件已创建:
ls你应该能看到
myapp.jar文件。
5. 运行 JAR 文件
- 运行 JAR 文件时需要指定主类。在
HelloWorld类中,我们可以在MANIFEST.MF中指定主类,或者直接在命令行中运行:java -cp myapp.jar com.example.myapp.HelloWorld
这种方式可以运行 JAR 文件中任意个类,只要你使用 cp 命令指定就行
6. 添加主类到 JAR 文件
为了使 JAR 文件可直接运行,可以添加主类到 MANIFEST.MF 文件中:
- 创建一个名为
MANIFEST.MF的文件,内容如下:Manifest-Version: 1.0 Main-Class: com.example.myapp.HelloWorld - 创建 JAR 文件时指定
MANIFEST.MF:jar cvfm myapp.jar MANIFEST.MF com/example/myapp/*.class
7. 直接运行 JAR 文件
现在你可以直接运行 JAR 文件,而不需要再指定主类:
java -jar myapp.jar
8. 用第三方包
java 文件中要用到的包是别人打包好的,我们编译时要通过添加参数来实现使用别人的包,如下:
编译:
javac --module-path /path/to/javafx-sdk/lib --add-modules javafx.controls HappyFaceFX.java
运行:
java --module-path /path/to/javafx-sdk/lib --add-modules javafx.controls HappyFaceFX
9. 用自己本地打好的包
首先,这是原始目录结构:
```bash
myapp
├── bin
│ ├── com
│ │ └── example
│ │ ├── myapp
│ │ ├── HelloWorld.class
│ │ └── Utils.class
│ │
│ │
│ └── myapp.jar
└── src
└── com
└── example
├── app
│ ├── HelloWorld.java
│ └── Utils.java
└── test
└── MainApp.java
然后创建一个新的结构如下:
myapp
├── bin
│ ├── com
│ │ └── example
│ │ ├── myapp
│ │ │ ├── HelloWorld.class
│ │ │ └── Utils.class
│ │ └── test
│ │ └── MainApp.class
│ └── myapp.jar
└── src
└── com
└── example
├── app
│ ├── HelloWorld.java
│ └── Utils.java
└── test
└── MainApp.java
这个 test 文件夹的 java 文件如下:
package com.example.test;
import com.example.myapp.Utils; // 导入 Utils 类
public class MainApp {
public static void main(String[] args) {
Utils.printMessage("Hello from MainApp!");
}
}
导入了 com. example. myapp 这个包中的 Utils 类,并且将这个设置为com. example. test 包。
编译这个文件方法
- 将 example 文件夹下的所有 java 文件一起编译,这样就不会出现依赖问题
- 编译时设置路径(-cp),在
src文件夹下使用如下命令:javac -cp ../bin com/example/test/MainApp.java -d ../bin - 结合(-cp)以及 jar 包也行,在
src文件夹下使用如下命令:javac -cp ../bin/myapp.jar com/example/test/MainApp.java -d ../bin
==最后,就是因为我设置这个包时有个目录,使用 javac 编译文件输出到具体目录时也是会产生相应目录结构,就是会多出文件夹==
运行这个文件方法
运行指令:
java com.example.test.MainApp
看情况需不需要链接类文件,好像在同一个包的根目录 com/example 下就不需要使用 -cp。不在同一个根目录下就要使用 -cp。
总之,如果不能运行就自己手动加上 -cp 就行了
--module-path 和 -cp 区别
--module-path 和 -cp (或 --class-path) 是 Java 中的两个不同选项,它们用于不同的场景,因为 Java 支持两种不同的代码组织方式:模块系统 和 类路径。
区别:
1. -cp(--class-path):
-cp 是用于指定 类路径 的选项,适用于传统的 Java 项目结构,即所有的 .class 文件和 JAR 文件都是通过类路径来管理和加载的。
- 使用场景:用于在传统的 Java 项目中查找
.class文件和 JAR 包。 - 适合的项目:适合未使用 Java 9 引入的模块系统的项目,或者依旧通过类路径进行管理的库和依赖。
示例:
javac -cp /path/to/library.jar YourProgram.java
java -cp /path/to/library.jar YourProgram
2. --module-path(-p):
--module-path 是用于 模块系统 的选项,这是 Java 9 引入的特性。在模块系统中,代码和依赖项(例如 JAR 文件)被打包为模块,每个模块都有一个明确的依赖关系和暴露的 API。
- 使用场景:用于指定模块路径(即模块化的 JAR 文件),适合 Java 9 及以上的项目,特别是那些使用了 Java 的模块系统的项目。
- 适合的项目:适合将代码和依赖项组织为模块的项目。例如,JavaFX 是基于模块系统的库。
示例:
javac --module-path /path/to/modules --add-modules javafx.controls YourProgram.java
java --module-path /path/to/modules --add-modules javafx.controls YourProgram
为什么 JavaFX 需要 --module-path?
JavaFX 自从 Java 9 起就成为了一个独立的模块(不再包含在 JDK 中)。因此,当你在编译和运行 JavaFX 应用时,你需要告诉 Java 编译器和运行时如何找到 JavaFX 模块,这就是为什么使用 --module-path 来指定 JavaFX 模块的路径。
示例解释:
javac --module-path /path/to/javafx-sdk/lib --add-modules javafx.controls HappyFaceFX.java
--module-path:指定 JavaFX SDK 的路径,其中包含 JavaFX 的模块化 JAR 文件。--add-modules javafx.controls:明确告诉编译器或运行时要加载javafx.controls模块,这是 JavaFX 提供的核心 UI 控件模块。
什么时候用 -cp 和 --module-path?
- 使用
-cp:当你使用的是非模块化的 Java 项目或依赖时,继续使用类路径(-cp)。 - 使用
--module-path:当你的项目或依赖是模块化的,特别是使用 Java 9 引入的模块系统时,比如 JavaFX。
小结
-cp适用于传统的类路径管理。--module-path适用于模块化的项目和库(如 Java 9 引入的模块系统)。
总结
你已经完成了以下步骤:
- 创建 Java 包。
- 编写 Java 文件并编译。
- 运行 Java 程序。
- 创建 JAR 文件。
- 添加主类到 JAR 文件并直接运行。
这种方法可以帮助你组织代码、简化项目管理,并且便于分发。