为方法参数分配新值是否有问题?

sle*_*ske 20 java eclipse compiler-warnings

Eclipse有一个选项可以警告赋值给方法的参数(在方法内),如:

public void doFoo(int a){
   if (a<0){
      a=0; // this will generate a warning
   }
   // do stuff
}
Run Code Online (Sandbox Code Playgroud)

通常我尝试激活(并注意)几乎所有可用的编译器警告,但在这种情况下,我不确定它是否值得.

我看到了改变方法中参数的合法情况(例如:允许参数"取消设置"(例如null)并自动替换默认值),但很少会导致问题,除非它可能有点混淆在方法中间重新分配参数.

你使用这样的警告吗?为什么/为什么不呢?

注意:

避免这种警告当然等同于制作方法参数final(只有这是编译器错误:-)).那么这个问题为什么我要在Java中的方法参数上使用关键字"final"?可能是相关的.

Mne*_*nth 13

令人困惑的部分是警告的原因.如果你在方法中重新分配参数一个新值(可能是有条件的),那么它就不清楚了,是什么.这就是为什么它被认为是好的风格,让方法 - 参数保持不变.

  • 将其清理为新的局部变量. (9认同)
  • @Mnementh,如果为此目的创建一个新的局部变量,为所有类似变量选择适当的名称可能会很棘手. (8认同)
  • 我不同意 - 输入通常需要消毒. (4认同)
  • @finnw:这实际上是我经常"打破"这条规则的最大原因.我只是缺乏创造力.:-) (2认同)
  • @finnw`inputSanitized`适合我. (2认同)

T.J*_*der 10

对我来说,只要你早点清楚地做到这一点,就没事了.正如你所说的那样,将其深入四个条件中间深入到30行函数中并不理想.

使用对象引用时,你显然必须要小心,因为调用你给出的对象上的方法可能会改变它的状态并将信息传递回调用者,但当然如果你已经在你自己的占位符中填充了那个信息没有沟通.

另一面是,声明新的变量并赋予该参数(如果需要的参数默认默认),它可能是更清晰,而且几乎肯定不会低效率 - 任何像样的编译器(无论是主编译器或JIT )在可行时将优化出来.

  • @OscarMk:我的观点恰恰如此:它不会.:-)所以(比方说)你收到了参数`obj`,并且如果存在某种条件,你会在函数顶部附近为它指定一个新的引用.在函数的底部附近,你调用`obj.foo()`.如果你已经为`obj`分配了一个新的引用,那么显然调用者的对象将不会收到`foo`调用,你的替换将会 - 但是在那里查看代码并不明显会发生这种情况. (2认同)

Pon*_*gge 8

分配方法参数并不是大多数人期望在大多数方法中发生的事情.由于我们在假设参数值是固定的情况下阅读代码,因此,如果仅通过惯例和最不惊讶原则,赋值通常被视为不良实践.

总是可以选择分配方法参数:通常本地临时副本就可以了.但一般来说,如果你发现需要通过参数重新分配来控制函数的逻辑,那么它可以从重构到更小的方法中受益.


Win*_*ith 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");
}
Run Code Online (Sandbox Code Playgroud)

许多人都希望在调用doFoo之后,myObject.Foo将等于"Bar".当然,它不会 - 因为Java不是通过引用传递,而是通过引用值传递 - 也就是说,引用的副本被传递给方法.重新分配到该副本只会在本地范围内产生影响,而不会在呼叫站点产生影响.这是最常被误解的概念之一.

  • 是的,但在这种特殊情况下,你指的是一个不懂语言如何运作的人.编译器警告不会防止这种情况发生. (3认同)
  • 实际上,Java方法只是按值调用.不过,我认为这与这个问题没什么关系. (2认同)