Java命令行程序是Java开发中最基础也是最核心的应用形式之一,它不依赖图形用户界面(GUI),而是通过控制台进行输入输出操作,广泛应用于工具开发、自动化脚本、后端服务、数据处理等领域,与Java图形界面程序或Web应用相比,命令行程序具有轻量级、启动快、资源占用少、易于集成到自动化流程等优势,尤其适合服务器环境或需要频繁执行特定任务的场景。

要创建一个Java命令行程序,首先需要理解Java的基本程序结构,一个标准的Java命令行程序通常包含一个或多个Java类,其中必须有一个包含public static void main(String[] args)方法的类,这是程序的入口点,当程序运行时,Java虚拟机(JVM)会从这个方法开始执行。args参数是一个字符串数组,用于接收从命令行传递给程序的参数,这些参数可以配置程序的行为,例如指定输入文件路径、设置运行模式或传递数值等。
程序开发与编译过程
开发Java命令行程序通常需要以下步骤:编写源代码、编译源代码、运行程序,编写源代码时,可以使用任何文本编辑器(如Notepad++、VS Code)或集成开发环境(IDE,如IntelliJ IDEA、Eclipse),以一个简单的“Hello, World!”程序为例,源代码如下:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
将上述代码保存为HelloWorld.java文件后,打开命令行工具(如Windows的CMD或PowerShell,Linux的Terminal),使用javac命令进行编译:
javac HelloWorld.java
编译成功后,会生成一个HelloWorld.class文件,这是Java字节码文件,接着使用java命令运行程序:

java HelloWorld
注意,运行时不需要加.class扩展名,因为java命令执行的是JVM中的字节码解释器,执行后,控制台会输出Hello World!。
命令行参数处理
命令行参数是命令行程序与用户交互的重要方式,通过args数组,程序可以接收外部输入的参数,以下程序接收两个参数并计算它们的和:
public class Adder {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage: java Adder <num1> <num2>");
return;
}
try {
double num1 = Double.parseDouble(args[0]);
double num2 = Double.parseDouble(args[1]);
System.out.println("Sum: " + (num1 + num2));
} catch (NumberFormatException e) {
System.out.println("Error: Please enter valid numbers.");
}
}
}
运行时需要传入两个参数,
java Adder 10.5 20.3
程序会输出Sum: 30.8,如果参数数量不正确或格式错误,程序会提示相应的错误信息,处理参数时,通常需要检查args.length以避免数组越界,并对参数类型进行转换和异常处理。

输入输出操作
Java命令行程序的输入输出主要通过System.in、System.out和System.err实现。System.out用于标准输出(通常打印到控制台),System.err用于标准错误输出(也打印到控制台,但通常以不同颜色标识),System.in用于标准输入(从键盘读取数据),更复杂的输入操作可以使用java.util.Scanner类,
import java.util.Scanner;
public class InputExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Hello, " + name + "!");
scanner.close();
}
}
运行程序后,用户可以在控制台输入姓名,程序会读取并输出问候语。
打包与可执行文件
为了方便分发和运行,可以将Java命令行程序打包成可执行的JAR(Java Archive)文件,创建一个MANIFEST.MF文件,指定主类(包含main方法的类):
Manifest-Version: 1.0
Main-Class: HelloWorld
然后使用jar命令打包:
jar cvfm HelloWorld.jar MANIFEST.MF HelloWorld.class
运行JAR文件时,使用以下命令:
java -jar HelloWorld.jar
这样,用户无需手动编译和设置类路径,直接运行JAR文件即可执行程序。
高级特性:多线程与网络编程
Java命令行程序也可以利用多线程和网络编程实现复杂功能,以下程序创建一个简单的多线程计数器:
public class MultiThreadExample {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread 1: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread 2: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
}
}
Java提供了java.net包用于网络编程,例如创建简单的HTTP客户端或服务器,实现命令行下的网络通信。
常用工具与库
开发Java命令行程序时,可以借助一些第三方库简化开发。
- Apache Commons CLI:用于解析命令行参数,支持短选项(如
-v)和长选项(如--verbose)。 - Log4j或SLF4J:用于日志记录,支持不同级别的日志输出(DEBUG、INFO、ERROR等)。
- Jackson或Gson:用于处理JSON格式的数据,适合需要与Web API交互的命令行程序。
性能优化与调试
对于性能要求较高的命令行程序,需要注意以下几点:
- 避免频繁的内存分配,尽量重用对象。
- 使用
StringBuilder代替字符串拼接,减少内存开销。 - 对于CPU密集型任务,可以考虑使用多线程或并行流(Java 8+)。
- 调试时,可以使用
System.out.println打印关键变量值,或使用IDE的调试功能设置断点、查看变量。
相关问答FAQs
Q1: 如何在Java命令行程序中读取用户输入的密码,且输入时不显示明文?
A1: 在Java中,可以使用Console类读取密码,该类提供了readPassword()方法,输入的字符不会显示在控制台上,示例代码如下:
import java.io.Console;
public class PasswordInput {
public static void main(String[] args) {
Console console = System.console();
if (console == null) {
System.out.println("No console available");
return;
}
char[] password = console.readPassword("Enter password: ");
System.out.println("Password entered: " + new String(password));
}
}
注意:Console类在某些IDE(如IntelliJ IDEA)中可能无法正常工作,建议在命令行环境中运行。
Q2: 如何在Java命令行程序中实现后台运行(如Linux中的nohup效果)?
A2: 在Linux或macOS中,可以使用nohup命令让程序在后台运行,即使关闭终端程序也会继续执行。
nohup java -jar MyProgram.jar > output.log 2>&1 &
nohup表示忽略挂断信号,>将标准输出重定向到output.log,2>&1将标准错误也重定向到同一文件,&表示在后台运行,在Windows中,可以使用start命令:
start /B java -jar MyProgram.jar 