Java CLI框架:Picocli、JCommander和Spring Shell

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

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

推荐