3

我们有一个很大的应用程序,它使用了很多Strings

  • 对于序列号
  • 产品名称
  • 对于订单号
  • 供客户参考
  • ... 还有很多 ...

不幸的是,我们的开发人员只是人类。有时String在调用方法时值会混淆。例如:

// this method
public void addProductToOrder(String order, String productname, String serialnumber);

// should be called like:
addProductToOrder(order, productname, serialnumber);

// but is sometimes mistakenly called as:
addProductToOrder(productname, serialnumber, order);

当您的方法采用大约 30 个这些参数时,很难检测到切换 2 个参数。(是的,它是那些繁重的业务应用程序之一)

旁注:如果我们创建自己的类SerialNumber来充当String. 但这似乎大错特错。

最近,我开始怀疑是否有一种方法可以使用自定义注释来检测混淆。毕竟,已经有像Nullable, NonNull... 这样的注释了,这并没有太大的不同。

我们想注释我们的源代码,例如这样:

public void addProductToOrder(@OrderReference String order, @ProductName String productname, @SerialNumber String serialnumber);

接下来,我们想找到一种方法,让我们的 IDE 检测到这里切换了 2 个参数。

@OrderReference String order = "ORDER_001";
@SerialNumber String sn = "0001-1213-007";
@ProductName String productname = "beer";
addProductToOrder(productname, serialnumber, order);
// should have been: addProductToOrder(order, productname, serialnumber);

我们正在使用 IntelliJ IDE。不编写 IDE 插件有什么可能?

4

2 回答 2

2

虽然您应该将 ControlAltDel 的评论作为最终解决方案,但 Intelij 确实有一个检查“可疑变量/参数名称组合”可能会有所帮助。您可以输入常用参数名称,如果它认为局部变量不匹配,它会警告您。

在此处输入图像描述 Intellij 的检查

于 2015-06-01T16:02:50.637 回答
2

您自己的解决方案是一个很好的解决方案:在代码中编写注释,并运行一个注释处理器,该处理器会在编译时警告您出现问题。

一种简单的方法是使用Checker Framework,它使您能够使用诸如@OrderReference, @SerialNumber,@ProductName等类型限定符来增强 Java 的类型系统。 Checker Framework 已经附带了示例检查器,可确保正确使用字符串,例如正则表达式,格式字符串、属性文件键和国际化。你可以从更简单的开始;事实上,您可以创建一个简单的类型检查器,而无需编写超出类型限定符注释定义的任何代码。

正如您也提到的,另一种方法是使用常规 Java 类型。如果可能,这也是一个很好的解决方案。但是,有一些原因可能是不可能或不可取的,包括:向后兼容性、更广泛的适用性、更丰富的语义、新的超类型、更精确的检查、运行时效率和代码混乱。有关这些问题的讨论,请参阅Checker Framework FAQ 中的“我应该使用可插入类型还是 Java 子类型? ”项。

另一种选择是将单个容器对象传递给您的方法,而不是传递 30 个参数。但是,这种方法在向后兼容性等方面存在一些相同的问题。此外,您仍然需要确保将值放入容器的正确插槽中,因此可插入类型检查仍然相关。

于 2015-06-02T09:45:18.277 回答