Java 方法参数混淆

Java 方法参数混淆,java,Java,通常,时间方法需要3个以上相同类型的参数,例如 void mymethod (String param1, String param2, String param3) 然后,客户机很容易混淆参数顺序,例如反转参数1和参数2: mymethod (param2, param1, param3); …这可能是花费大量时间调试本应是一件小事的原因。 关于如何避免此类错误(单元测试除外)的任何提示?在支持它们的其他语言中,使用命名参数是解决这一问题的明显方法。提供了一些技巧,包括在Java中提供假命

通常,时间方法需要3个以上相同类型的参数,例如

void mymethod (String param1, String param2, String param3)
然后,客户机很容易混淆参数顺序,例如反转参数1和参数2:

mymethod (param2, param1, param3);
…这可能是花费大量时间调试本应是一件小事的原因。
关于如何避免此类错误(单元测试除外)的任何提示?

在支持它们的其他语言中,使用命名参数是解决这一问题的明显方法。提供了一些技巧,包括在Java中提供假命名参数的方法。

如果您的方法使用了4个以上的参数,那么您就得到了一个丑陋的API

为什么所有的参数类型都是字符串。创建类来表示那些类似字符串的值,而不是将字符串用于所有内容,这有意义吗

例如,使用名称类而不是字符串,因此创建一个人可能如下所示

Person create( FirstName firstName, LastName lastName, Address address );   
通常,程序使用字符串作为各种数据的容器,这导致程序很少验证数据。通过创建专家类,即使它们拥有一个字符串属性,也可以向工厂添加一些验证,并确保它是一个有效值。当然,字符串容器也应该是不可变的——只有getter而不是setter


查看Josh Bloch,了解更多提示和智慧。

您正在搜索:

最好的解决方案是使用数据类而不是许多参数。看起来您太依赖于基本对象(字符串、整数等),只需为相关数据创建类。如果没有良好的关系,那么您也可以使用具有单个属性的类,这样,如果排序不正确,编译器就会抱怨,如果您在某个时候需要更多属性,那么您的代码是可扩展的(即,现在的方法不仅需要项的名称,还需要id)


如果没有选择,那么您可以尝试坚持参数排序的模式(类似于“参数1始终是源字符串,…”)

使用javadoc,它是您的朋友

对于任何好的IDE,将鼠标悬停在方法名称上都会为您提供一个包含有用信息的工具提示窗口。

我知道,在Eclipse中,如果您的javadoc使用@param标记,那么您混淆哪个参数是哪个参数的可能性将大大降低。

您在Java中的最佳选择是创建一个简单的参数JavaBean,即普通的旧Java对象(POJO),每个参数都有getter和setter。然后,您的方法签名可以是:

void mymethod (Parameters parametersObject)
JavaBean的参数有setParam1(…)、setParam2(…)、setParam3(…)等等,甚至可以进行一些基本的内部验证,提供默认值,等等


如果您不想创建Parameters对象,请使用Map,但是您必须在方法内部进行额外的检查以查找缺少的参数。此外,Map的键必须是众所周知的,即在方法外部和方法内部都是众所周知的。

就像volothamp在其an中提到的那样命名参数会有很大帮助,您可以在Java中模拟类似的东西,如本文所述

大多数情况下,尤其是如果您使用的是第三方使用的api,您希望拥有存储构造函数参数的数据对象,或者具有三个以上参数的方法。这是一种称为的模式。这使您能够在参数对象中执行输入检查,并保持方法更干净等

如果您创建的参数对象只有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);
这是更多的代码,但可读性更高。如果要减少所需的代码行,可以使用。让setter返回他们处理的对象。现在的代码如下所示:

public printAddress(Address address) {...}
printAddress(new Address().setName(name).setStreet(street).setCity(city))

乍一看,这看起来很奇怪,但如果您习惯了,它会使代码变得更小,更具可读性,并且您需要处理来自客户端的所有调试问题。

在您的示例中,最好使用具有属性FirstName和LastName的名称类,这样就不需要使用一个参数…即(我想)这正是您试图解释的。不是真的。很多小班比大班都好。当创建一个人员家庭时,最好创建一次姓氏并将其传递给每个创建的人员。这意味着姓氏只需要验证一次,而不是对家庭中的每个成员验证一次。如果家族有一个不同的姓氏,然后自然会创建另一个姓氏。有时一个人也可能有多个名字,每个名字都由一个名字的实例表示。在这种情况下,也许GivenName是一个更好的类名。无论哪种方法,校长都可以通过保持我们的类小而简单来应用我们的名字将它们混合在一起以构建更大、更有用的复合类。从我的进一步示例中可以明显看出,我的建议是无限好、更具可扩展性的。这种垃圾,一系列大量字符串参数不是类型安全的,因为它很容易在错误的位置转置错误的参数。查看我的答案,以获得更好的示例。在特殊情况下,编译器可以帮助您注意错误,因为将错误的类型参数放在了错误的位置。使用它…我同意mP,命名参数仅适用于一个方法有多个可选参数组合的情况(这通常意味着应该有多个方法或不同类型的参数).感谢你的投票结果,不管你是谁。请确切地向我们解释你认为文件是件坏事吗?