不应分配参数“ foo”,这有什么害处?
问题内容:
比较这种方法:
void doStuff(String val) {
if (val == null) {
val = DEFAULT_VALUE;
}
// lots of complex processing on val
}
…对此方法:
void doStuff(String origVal) {
String val = origVal;
if (val == null) {
val = DEFAULT_VALUE;
}
// lots of complex processing on val
}
对于前一种方法,Eclipse发出警告“不应分配参数’val’”。为什么?
在我看来,前者更清洁。一方面,这并不会迫使我想出 两个 好名字val
(想出一个好名字已经够难了)。
(注意:假定val
在封闭的类中没有命名字段。)
问题答案:
看起来好像没有人在这里做过举动。
我通常不会更改参数,实际上,我倾向于标记我的参数final
以明确禁止使用它。原因如下:
-
分配参数可能会 与尝试将其用作“输出参数” 混淆,请参见:javapractices.com,清晰度就是一切
-
支持不可变性 ,这和其他任何参数一样适用于参数值。基元只是同一事物的简并案例,(通常)更容易推断出不可变的变量。参考,有效的Java项目13或javapractices.com
-
最后(NPI), 自由使用final ,javapractices.com。无论它在参数签名中是多么丑陋,我相信它都倾向于识别意外错误,并且突出显示了可变变量,通常应该是例外。在大多数代码中,大多数可变变量都是出于懒惰,或者是认为它对性能有一定影响,因此,如果明智地选择,不变和命名良好的中间计算,则更清晰,更易于阅读和验证,并且可以针对性能进行干净优化没有您的帮助。
我不能抽象地对您的特定情况进行明智地讲,但是除非我可能做不同的其他所有事情,否则我赞成:
void doStuff(final String origVal)
{
final String valOrDefault = (origVal == null) ? DEFAULT_VALUE : origVal;
//lots of complex processing on valOrDefault
}
甚至(假设在一个只有一个参数的实数方法中您将无法处理空值,它必须是更复杂的东西的一部分)…而且,通常,接受null
为参数的方法应明确记录为:这样做,仅仅是为了加强这样的假设,即空参数应该是例外。在第二种方法中,您甚至可以使用@NonNull
注解。
/**
* @param origVal string giving value, possibly null, in which case DEFAULT_VALUE is assigned
*/
void doStuff(final String origVal, ... )
{
final String valOrDefault = (origVal == null) ? DEFAULT_VALUE : origVal;
// similar mucking about to make all the parameters behave, separate from
// actually operating on them...
...
reallyDoStuff(valOrDefault,...);
}
private void reallyDoStuff(final String value, ...)
{
assert (value != null);
// do your complex processing
}