Java 命令行界面(第 3 部分):jbock

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(246)   2023-12-05 15:34:57

在本系列关于 Java 命令行解析 的前两篇文章中,我查看了 Apache Commons CLIargs4j 库。在本系列的第三篇文章中,我研究了 jbock,它自称为“非常简单的 CLI 解析器”。

我关于 Java 命令行解析的帖子使用了基于向 Java 应用程序提供必需的文件名和可选的详细标志的示例。这篇文章中使用相同的方法来演示 jbock 1.8。示例类的完整源代码在GitHub 上可用,但是jbock (Main_Parser) 生成的代码是可以生成的,因此不可用。

jbock 用于命令行处理的方法不同于前面介绍的两个解析库所使用的方法。前面介绍的库需要 Java 代码来解析要针对库的 JAR 构建和执行的命令行参数。换句话说,库的 JAR 需要同时位于编译时 (javac) 类路径和运行时 Java 启动器 (java) 类路径中。 jbock 方法依赖于仅在编译时包含 jbock JAR。 jbock 方法生成完全独立于 jbock 库的 Java 源代码。例如,可以选择运行 jbock 一次生成这些 Java 源代码文件,然后对这些生成的文件进行版本控制,并且从那时起只构建和运行生成的文件,而无需构建或运行 jbock 的 JAR。只有在需要重新生成生成的 Java 源代码时才需要 jbock JAR。因为生成的代码是基于自定义 Java 类上的注释生成的,所以在大多数情况下,jbock 代码生成很可能作为正常构建的一部分执行,而不是对生成的源代码进行版本控制。

在大多数情况下,在使用 jbock 解析命令行参数时,我会使用名称为“Arguments”或“CommandLine”的自定义类。但是,对于这篇文章,我使用一个简单的 Main 类来更类似于本系列其他文章中其他命令行解析库所使用的方法的示例。与 args4j 一样,jbock 在命令行处理的“定义”阶段使用注释。然而,jbock 的注释是在类的构造函数及其参数上,而不是 args4j 的注释类字段的方法。 jbock 基于构造函数的注释方法在下一个代码清单中进行了演示。

jbock 命令行选项的“定义”

@CommandLineArguments
public Main(
   @ShortName('v') @LongName("verbose") @Description("Verbosity enabled?")
   final boolean newVerbose,
   @ShortName('f') @LongName("file") @Description("File name and path")
   final Optional<String> newFileName)
{
   verbose = newVerbose;
   file = newFileName.orElse("");
}
// . . .

下一个代码清单演示了使用 jbock 进行命令行处理的“解析”阶段。

使用 jbock“解析”命令行选项

final Main_Parser parser = new Main_Parser();
final Main_Parser.Binder binder = parser.parse(arguments);
final Main main = binder.bind();

上面代码清单中显示的 Main_Parser 类是由 jbock 根据第一个代码清单中显示的注释生成的。 jbock库通过处理Main类的注解来决定如何构建Main_Parser类。生成的类名是基于带有jbock注解的类名,由_Parser拼接而成。例如,如果我的带有 jbock 注释构造函数和构造函数参数的类被命名为“Arguments”,生成的类将被命名为“Arguments_Parser”。

在生成的 Main_Parser 类的实例在命令行参数上调用了 parse 之后,该实例的 bind() 方法被调用以返回一个实例原始注释的 Main 类。此时的“询问”过程仅包括通过其公共“get”方法访问该 Main 实例的属性。这在下一个代码清单中进行了演示。

jbock 命令行处理的“询问”阶段

out.println("The file '" + main.getFile() + "' was provided and verbosity is set to '"
   + main.isVerbose() + "'.");

下面的屏幕快照演示了使用 jbock 解析命令行选项的代码。

如果需要帮助或使用信息,也可以从生成的 *_Parser(本例中为 Main_Parser)类中检索。具体来说,生成的 *_Parser 类包括一个嵌套的 Option 枚举,表示各种选项。可以迭代这些选项的枚举值来检索关于每个选项的元数据。在下面的代码清单中,describe(int) 方法在每个选项的枚举值上被调用(传入的整数是要缩进的空格数)。

使用jbock获取使用详情

final Main_Parser parser = new Main_Parser();
if (arguments.length < 1)
{
   for (final Main_Parser.Option option : Main_Parser.Option.values())
   {
      out.println(option.describe(3));
   }
   System.exit(-1);
}

接下来显示的屏幕快照演示了此代码如何打印出选项及其描述。

这篇文章中讨论的源代码可在 GitHub 上获取

以下是在选择框架或库以帮助在 Java 中进行命令行解析时要考虑的 jbock 的一些其他特性。

  • jbock 以开源的形式提供。
  • 当前版本的 jbock (1.8) 需要 Java SE 8
  • jbock 没有第三方或外部依赖项。
  • jbock 1.8 JAR (jbock-1.8.jar) 的大小大约为 131 KB,但这并不像类似库那么重要,因为在运行时不需要此 JAR(生成的代码独立于 JAR ).
  • 我没有演示 jbock 强制要求存在必需的命令行参数,因为它有意不支持该功能。 README 指出,“故意简单:没有转换器、默认值或需要检查。使用 Java 8,手动添加这些东西很容易。”

jbock 区别于大多数其他基于 Java 的命令行解析库的最明显特征是完全在编译时生成解析代码,不会留下对 jbock 库的运行时依赖性。在关注加载类的数量或表达的类路径的大小的情况下,这将是一个明显的优势。 README 列出了多个“让 [jbock] 与众不同”的项目。其中包括“无反射,纯静态分析”和“通过构造函数方便、灵活的属性绑定”。

标签2: Java教程
地址:https://www.cundage.com/article/jcg-java-command-line-interfaces-part-3-jbock.html

相关阅读

Java HashSet 教程展示了如何使用 Java HashSet 集合。 Java哈希集 HashSet 是一个不包含重复元素的集合。此类为基本操作(添加、删除、包含和大小)提供恒定时间性...
SpringApplicationBuilder 教程展示了如何使用 SpringApplicationBuilder 创建一个简单的 Spring Boot 应用程序。 春天 是用于创建企业应...
通道是继 buffers 之后 java.nio 的第二个主要新增内容,我们在之前的教程中已经详细了解了这一点。通道提供与 I/O 服务的直接连接。 通道是一种在字节缓冲区和通道另一端的实体(通...
课程大纲 Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了一个分布式的、支持多租户的全文搜索引擎,带有 HTTP Web 界面和无模式的 JSON 文档。 Elasti...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Java 是用于开发各种桌面应用程序、Web 应用程序和移动应用程序的最流行的编程语言之一。以下文章将帮助您快速熟悉 Java 语言,并迈向 API 和云开发等更复杂的概念。 1. Java语言...
Java中的继承是指子类继承或获取父类的所有非私有属性和行为的能力。继承是面向对象编程的四大支柱之一,用于提高层次结构中类之间的代码可重用性。 在本教程中,我们将了解 Java 支持的继承类型,...
Java Message Service 是一种支持正式通信的 API,称为 网络上计算机之间的消息传递。 JMS 为支持 Java 程序的标准消息协议和消息服务提供了一个通用接口。 JMS 提...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...