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

时间:2010-02-09 13:36:08

标签: java eclipse compiler-warnings

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?可能是相关的。

8 个答案:

答案 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)

你应该编写没有副作用的代码:每个方法都应该是一个不会改变的函数。否则它是命令,它可能很危险。

请参阅DDD网站上commandfunction的定义:

  

功能:   计算并返回没有可观察副作用的结果的操作。

     

命令:对系统进行一些更改的操作(for   例如,设置变量)。一个   有意创造的操作   副作用。