CLI 框架用于 Java:打造强大的控制台应用程序
使用 Java 开发控制台(CLI)应用程序是每位开发者都会遇到的任务。通过 main(String[] args) 手动处理命令行参数很快就会变得繁琐且容易出错。幸运的是,Java 生态系统中存在成熟的框架,它们负责解析、验证、自动补全和帮助文档生成。在本文中,我们将探讨三种领先的工具:Picocli、JCommander 和 Spring Shell。
1. Picocli — 现代且高性能
Picocli 是一个体积小巧(仅 1.5 MB)的框架,无需外部依赖。它支持注解、Bash/Zsh 自动补全以及内置的帮助文档生成。Picocli 非常适合微服务和命令行工具。
主要功能:
- 注解
@Command、@Option、@Parameters - 嵌套子命令(subcommands)
- 类型化参数(int、boolean、enum、集合)
- 自动验证(必填参数、范围)
- 彩色输出和进度条
- GraalVM 原生编译
代码示例:
import picocli.CommandLine;import picocli.CommandLine.Command;import picocli.CommandLine.Option;import picocli.CommandLine.Parameters;
@Command(name = "greet", description = "问候用户")public class GreetCommand implements Runnable {
@Option(names = {"-n", "--name"}, description = "用户名", required = true) private String name;
@Option(names = {"-c", "--count"}, description = "重复次数", defaultValue = "1") private int count;
@Parameters(index = "0", description = "消息", defaultValue = "你好") private String message;
@Override public void run() { for (int i = 0; i < count; i++) { System.out.println(message + ", " + name + "!"); } }
public static void main(String[] args) { int exitCode = new CommandLine(new GreetCommand()).execute(args); System.exit(exitCode); }}运行:java GreetCommand -n 世界 -c 2 "你好" 将输出:
你好, 世界!你好, 世界!2. JCommander — 久经考验
JCommander 是最古老的 CLI 框架之一(自 2010 年起),被 Jenkins 和 TestNG 等项目使用。它支持注解、复杂类型和国际化。JCommander 以简单的 API 和优秀的文档著称。
关键特性:
- 带有名称和描述的
@Parameter注解 - 通过
JCommander.addCommand()支持嵌套命令 - 通过自定义
IParameterValidator进行验证 - 使用
usage()生成帮助文档 - 处理配置文件
代码示例:
import com.beust.jcommander.JCommander;import com.beust.jcommander.Parameter;import com.beust.jcommander.Parameters;
@Parameters(commandDescription = "计算器")public class CalculatorCommand {
@Parameter(names = {"--a"}, description = "第一个数字", required = true) private int a;
@Parameter(names = {"--b"}, description = "第二个数字", required = true) private int b;
@Parameter(names = {"--op"}, description = "操作:add/sub/mul/div") private String operation = "add";
public void run() { double result; switch (operation) { case "add": result = a + b; break; case "sub": result = a - b; break; case "mul": result = a * b; break; case "div": result