通常,时间方法需要3个以上的参数,这些参数都是相同的类型,例如
void mymethod (String param1, String param2, String param3)
然后客户端很容易混淆参数命令,例如反转param1和param2:
mymethod (param2, param1, param3);
......这可能是花费大量时间调试应该是一件小事的原因。 关于如何避免这种错误的任何提示(除了单元测试)?
答案 0 :(得分:7)
答案 1 :(得分:4)
使用javadoc,它是你的朋友。
使用任何好的IDE,对方法名称进行鼠标悬停应该会为您提供一个包含有用信息的工具提示窗口 我知道使用Eclipse,如果你的javadoc使用了@param标签,你混淆哪个参数的可能性会大大降低。
答案 2 :(得分:3)
就像在答案中提到的volothamp一样。命名参数可以提供很多帮助,您可以在Java中模拟类似于它们的内容,如question中所述。
大多数情况下,特别是如果您使用的是第三方使用的api,您希望拥有存储构造函数的参数的数据对象或者需要多于三个参数的方法。这是一种名为parameter objects的模式。这使您可以在参数对象中进行输入检查,并使方法更清晰等。
如果创建一个只有setter的参数对象,则客户端可以清楚地命名,以查看其数据的放置位置。就像在这个例子中一样:
public printAddress(String name, String street, String city) {...}
print address(name, street, city);
如果你使用参数对象,你会有类似的东西:
public printAddress(Address address) {...}
Address address = new Address();
address.setName(name);
address.setStreet(street);
address.setCity(city);
printAddress(address);
这是更多代码,但它更具可读性。如果您想减少所需的代码行,可以使用method chaining。让setter返回他们工作的对象。代码现在看起来像这样:
public printAddress(Address address) {...}
printAddress(new Address().setName(name).setStreet(street).setCity(city))
第一眼看上去很奇怪,但是如果你已经习惯了它会使代码变得更小,你想要处理来自客户的所有调试问题。
答案 3 :(得分:1)
最好的解决方案是使用数据类而不是许多参数。看起来好像你过分依赖原始对象(字符串,整数,......),只需为相关数据创建类。如果没有良好的关系,那么你也可以使用具有单个属性的类,这样如果排序不正确,编译器会抱怨,如果你在某些时候需要更多的属性,你的代码是可扩展的(即一个方法现在不仅仅是需要一个项目的名称,但也需要id)。
如果这不是选项,那么你可以尝试坚持参数排序的模式(“参数1始终是源字符串,......”)
答案 4 :(得分:0)
在支持它们的其他语言中,使用命名参数是处理此问题的明显方法。 http://www.artima.com/weblogs/viewpost.jsp?thread=118828有一些提示,包括在Java中提供虚假命名参数的方法。
答案 5 :(得分:-1)
如果您的方法需要超过4个参数,那么您将获得一个丑陋的API。
为什么所有参数类型都是字符串。创建类来表示那些类似于String的值是否有意义,而不仅仅是使用String来进行翻转。
例如,使用Name类而不是String,因此创建Person可能看起来像这样......
Person create( FirstName firstName, LastName lastName, Address address );
程序通常使用String作为各种数据的容器,这会导致很少有程序很少验证其数据。通过创建专家类,即使它们包含单个String属性,也可以向工厂添加一些验证并确保它是有效值。当然,你的字符串容器也应该是不可变的 - getter只是没有setter。
看看Josh Bloch的Java Puzzlers,了解更多提示和智慧。
答案 6 :(得分:-1)
Java中最好的选择是创建一个简单的参数JavaBean - 即一个普通的旧Java对象(POJO),每个参数都有getter和setter。然后,您的方法签名可以是:
void mymethod (Parameters parametersObject)
和参数JavaBean将有setParam1(...),setParam2(...),setParam3(...)等,甚至可以做一些基本的内部验证,提供默认值,等等
如果您不想创建Parameters对象,请使用Map,但是您必须在方法内部进行额外的检查以查找缺少的参数。此外,地图的关键必须是众所周知的 - 也就是说,在方法之外以及方法内部都知道。