我们有一个很大的应用程序,它使用了很多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插件有什么可能?
答案 0 :(得分:2)
虽然您应该将ControlAltDel的评论作为最终解决方案,但Intelij确实有一个检查"可疑变量/参数名称组合"这可能有所帮助。您可以输入常用参数名称,如果它认为局部变量不匹配,它会发出警告。
答案 1 :(得分:2)
您自己的解决方案很好:在代码中编写注释,并运行注释处理器,在编译时向您发出警告。
执行此操作的一种简单方法是使用Checker Framework,这样您就可以使用类型限定符(例如@OrderReference
,@SerialNumber
,{{1}来增强Java的类型系统Checker Framework已经附带了示例检查器,可以确保正确使用字符串,例如正则表达式,格式字符串,属性文件密钥和国际化。你可以从更简单的事情开始;实际上,除了类型限定符注释的定义之外,您还可以创建一个简单的类型检查器without writing any code。
另一种方法是使用常规Java类型,如您所述。如果可能,这也是一个很好的解决方案。但是,有一些原因可能是不可能或不可取的,包括:向后兼容性,更广泛的适用性,更丰富的语义,新的超类型,更精确的检查,运行时效率和代码混乱。有关这些问题的讨论,请参阅" Should I use pluggable types or Java subtypes?"在Checker Framework常见问题解答中。
另一种方法是将单个容器对象传递给方法,而不是传递30个参数。但是,这种方法存在一些与向后兼容性等相同的问题。此外,您仍然需要确保将值放入容器的正确插槽中,因此可插入类型检查仍然相关。