Eclipse有一个选项可以警告赋值给方法的参数(在方法内),如:
public void doFoo(int a){
if (a<0){
a=0; // this will generate a warning
}
// do stuff
}
通常我会尝试激活(并注意)几乎所有可用的编译器警告,但在这种情况下,我不确定它是否值得。
我看到了更改方法中参数的合法情况(例如:允许参数“取消设置”(例如null)并自动替换默认值),但很少会导致问题,除非它可能在方法中间重新分配参数有点令人困惑。
你使用这样的警告吗?为什么/为什么不呢?
注意:
避免这种警告当然等同于制作方法参数final
(只有这时它才是编译器错误:-))。所以这个问题Why should I use the keyword "final" on a method parameter in Java?可能是相关的。
答案 0 :(得分:13)
令人困惑的部分是警告的原因。如果你在方法中重新分配参数一个新值(可能是有条件的),那么它就不清楚了,是什么。这就是为什么它被认为是一种好的风格,让方法 - 参数保持不变。
答案 1 :(得分:9)
对我来说,只要你早点清楚地做到这一点,就没事了。正如你所说的那样,将其深入四个条件中间深入到30行函数中并不理想。
使用对象引用时,显然必须要小心,因为调用给定对象的方法可能会更改其状态并将信息传递给调用者,但当然如果您已经在自己的占位符中进行了操作,该信息未被传达。
另一方面是声明一个新变量并将参数(或者参数需要默认的默认值)分配给它可能更清晰,并且几乎肯定不会效率低 - 任何体面的编译器(无论是主编译器)或者JIT)会在可行时对其进行优化。
答案 2 :(得分:8)
分配方法参数并不是大多数人期望在大多数方法中发生的事情。由于我们在假设参数值是固定的情况下阅读代码,因此,如果仅按惯例并且 principle of least astonishment ,则通常会将分配视为不良做法。
总是可以选择分配方法参数:通常本地临时副本就可以了。但通常,如果您发现需要通过参数重新分配来控制函数的逻辑,那么它可以从重构到更小的方法中受益。
答案 3 :(得分:7)
如果参数是引用类型,则重新分配给方法参数变量通常是错误的。
请考虑以下代码:
MyObject myObject = new myObject();
myObject.Foo = "foo";
doFoo(myObject);
// what's the value of myObject.Foo here?
public void doFoo(MyObject myFoo){
myFoo = new MyObject("Bar");
}
很多人都希望在调用doFoo之后,myObject.Foo将等于“Bar”。当然,它不会 - 因为Java不是通过引用传递,而是 传递参考值 - 也就是说,副本将引用传递给方法。重新分配到该副本只会在本地范围内产生影响,而不会在呼叫站点产生影响。这是最常被误解的概念之一。
答案 4 :(得分:1)
不同的编译器警告可能适用于不同的情况。当然,有些适用于大多数或所有情况,但这似乎不是其中之一。
我会想到这个特殊的警告,因为编译器会为您提供警告,让您在需要时重新分配方法参数,而不是不应重新分配方法参数的规则。你的例子构成了一个完全有效的案例。
答案 5 :(得分:0)
我有时会在以下情况下使用它:
void countdown(int n)
{
for (; n > 0; n--) {
// do something
}
}
避免在for循环中引入变量 i 。通常我只在非常短的函数中使用这些“技巧”。
就我个人而言,我非常不喜欢以这种方式纠正函数内部的参数。我更喜欢通过断言抓住这些并确保合同是正确的。
答案 6 :(得分:0)
我通常不需要为方法参数赋值。
至于最佳实践 - 警告还可以避免在面对如下代码时出现混淆:
public void foo() {
int a = 1;
bar(a);
System.out.println(a);
}
public void bar(int a) {
a++;
}
答案 7 :(得分:-1)