在编译期间验证传递给构造函数的参数

Validate parameters passed into Constructors during compile time

在一个拥有数万个 Java 文件的大型项目中,有几个 Java class 开发人员可以将字符串作为参数传递给构造函数 class 我已经实现了

public byte[] getProductReport(List<String> products, Date from, Date to) {
    // ... do some stuff before...

    List<ReportParameterDto> reportParameters = new ArrayList<>();
    reportParameters.add(new ReportParameterDto("From (YYYY.MM.DD)", ParameterType.DATE, from));
    reportParameters.add(new ReportParameterDto("To_(YYYY.MM.DD)", ParameterType.DATE, to));
    reportParameters.add(new ReportParameterDto("Products", ParameterType.SELECT, someList));

    return ReportFromCRServerHelper.downloadReport("ProductReporot", reportParameters, ReportFormat.PDF);
}

如果开发人员使用错误的字符串值下载请求的报告(从远程报告服务器)将在运行时失败。

在这个例子中,我想在编译期间进行一些验证检查,以避免在客户发现这些错误之前。

我有 API 方法从我希望使用的报告中获取参数值 在上述方法的编译过程中。

在我的示例中,编译应该失败并抛出一个错误,突出显示参数应该如何显示:

 "From (JJJJ-MM)" is invalid --> should be "From_(JJJJ-MM)"
 "Products" is invalid --> should be "PRODUCT_LIST"

我可以通过 JAVAX 注释处理检测这些参数(在上面的 ReportParameterDto 构造函数中使用)吗?

我发现的少数教程/博客涉及验证方法签名中的参数,而不是传递给方法的值。

或者是否有更优雅的工具可用?

Checker Framework 这样的 compile-time 工具可以验证方法或构造函数的参数。您注释参数类型以指示允许的值,然后当 javac 运行时,如果参数可能与参数不兼容,它会发出警告。

如果可能的值数量有限,那么您可以使用 Fake Enum Checker 将字符串或整数视为枚举值。 (使用 Java enum 也是一个好主意,但可能不可行或不方便,因为其他代码需要字符串或整数。)

如果可能值的数量没有限制,那么您可以使用 Constant Value Checker——例如,提供任何常量字符串参数必须满足的正则表达式。

如果您想要的功能不同于随 Checker Framework 分发的检查器中可用的功能,您也可以 define your own compile-time validation