eclipse 为方法参数分配新值是否有问题?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2229389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it problematic to assign a new value to a method parameter?
提问by sleske
Eclipse has an option to warn on assignment to a method's parameter (inside the method), as in:
Eclipse 有一个选项来警告分配给方法的参数(在方法内部),如下所示:
public void doFoo(int a){
if (a<0){
a=0; // this will generate a warning
}
// do stuff
}
Normally I try to activate (and heed) almost all available compiler warnings, but in this case I'm not really sure whether it's worth it.
通常我会尝试激活(并注意)几乎所有可用的编译器警告,但在这种情况下,我不确定这是否值得。
I see legitimate cases for changing a parameter in a method (e.g.: Allowing a parameter to be "unset" (e.g. null) and automatically substituting a default value), but few situations where it would cause problems, except that it might be a bit confusing to reassign a parameter in the middle of the method.
我看到在方法中更改参数的合法情况(例如:允许参数“未设置”(例如 null)并自动替换默认值),但很少有会导致问题的情况,除了它可能有点混淆在方法中间重新分配参数。
Do you use such warnings? Why / why not?
你使用这样的警告吗?为什么/为什么不?
Note:
笔记:
Avoiding this warning is of course equivalent to making the method parameter final
(only then it's a compiler error :-)). So this question Why should I use the keyword "final" on a method parameter in Java?might be related.
避免这个警告当然等同于设置方法参数final
(只有这样它才是编译器错误:-))。所以这个问题为什么我应该在 Java 的方法参数上使用关键字“final”?可能有关系。
采纳答案by T.J. Crowder
For me, as long as you do it early and clearly, it's fine. As you say, doing it buried deep in four conditionals half-way into a 30-line function is less than ideal.
对我来说,只要你早点做清楚,就可以了。正如您所说,在 30 行函数的中途深埋在四个条件中是不太理想的。
You also obviously have to be careful when doing this with object references, since calling methods on the object you were given may change its state and communicate information back to the caller, but of course if you've subbed in your own placeholder, that information is not communicated.
显然,在使用对象引用执行此操作时也必须小心,因为在给定的对象上调用方法可能会更改其状态并将信息传递回调用者,但是当然,如果您已经替换了自己的占位符,则该信息没有沟通。
The flip side is that declaring a new variable and assigning the argument (or a default if argument needs defaulting) to it may well be clearer, and will almost certainly not be less efficient -- any decent compiler (whether the primary compiler or a JIT) will optimize it out when feasible.
另一方面是声明一个新变量并为其分配参数(如果参数需要默认,则为默认值)可能会更清晰,并且几乎肯定不会降低效率——任何像样的编译器(无论是主编译器还是 JIT ) 将在可行时对其进行优化。
回答by Mnementh
The confusing-part is the reason for the warning. If you reassign a parameter a new value in the method (probably conditional), then it is not clear, what a is. That's why it is seen as good style, to leave method-params unchanged.
令人困惑的部分是警告的原因。如果您在方法中为参数重新分配一个新值(可能是有条件的),则不清楚 a 是什么。这就是为什么保持方法参数不变被视为良好风格的原因。
回答by Pontus Gagge
Assigning a method parameter is not something most people expectto happen in most methods. Since we read the code with the assumption that parameter values are fixed, an assignment is usually considered poor practice, if only by convention and the principle of least astonishment.
分配方法参数不是大多数人期望在大多数方法中发生的事情。由于我们在假设参数值是固定的情况下阅读代码,因此赋值通常被认为是糟糕的做法,如果只是按照惯例和最小惊讶原则。
There are always alternatives to assigning method parameters: usually a local temporary copy is just fine. But generally, if you find you need to control the logic of your function through parameter reassignment, it could benefit from refactoring into smaller methods.
分配方法参数总是有其他选择:通常本地临时副本就可以了。但通常,如果您发现需要通过参数重新分配来控制函数的逻辑,则可以从重构为更小的方法中受益。
回答by Winston Smith
Reassigning to the method parameter variable is usually a mistake if the parameter is a reference type.
如果参数是引用类型,则重新分配给方法参数变量通常是错误的。
Consider the following code:
考虑以下代码:
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");
}
Many people will expect that at after the call to doFoo, myObject.Foo will equal "Bar". Of course, it won't - because Java is not pass by reference, but pass by reference value- that is to say, a copy of the reference is passed to the method. Reassigning to that copy only has an effect in the local scope, and not at the callsite. This is one of the most commonly misunderstood concepts.
许多人会期望在调用 doFoo 之后,myObject.Foo 将等于“Bar”。当然,它不会——因为Java不是通过引用传递,而是通过引用值传递——也就是说,将引用的副本传递给方法。重新分配给该副本仅在本地范围内有效,而在调用点无效。这是最常被误解的概念之一。
回答by danben
Different compiler warnings can be appropriate for different situations. Sure, some are applicable to most or all situations, but this does not seem to be one of them.
不同的编译器警告可能适用于不同的情况。当然,有些适用于大多数或所有情况,但这似乎不是其中之一。
I would think of this particular warning as the compiler giving you the option to be warned about a method parameter being reassigned when you need it, rather than a rule that method parameters should not be reassigned. Your example constitutes a perfectly valid case for it.
我会认为这个特殊警告是编译器为您提供了在需要时警告方法参数被重新分配的选项,而不是不应重新分配方法参数的规则。您的示例构成了一个完全有效的案例。
回答by Jean-Philippe Caruana
You shoud write code with no side effect : every method shoud be a functionthat doesn't change . Otherwise it's a commandand it can be dangerous.
你应该编写没有副作用的代码:每个方法都应该是一个不会改变的函数。否则它是一个命令,它可能是危险的。
See definitions for commandand functionon the DDD website :
Function: An operation that computes and returns a result without observable side effects.
Command: An operation that effects some change to the system (for example, setting a variable). An operation that intentionally creates a side effect.
功能:计算并返回结果而没有可观察到的副作用的操作。
命令:一种对系统产生影响的操作(例如,设置一个变量)。一种有意产生副作用的操作。
回答by Maurits Rijk
I sometimes use it in situations like these:
我有时会在这样的情况下使用它:
void countdown(int n)
{
for (; n > 0; n--) {
// do something
}
}
to avoid introducing a variable iin the for loop. Typically I only use these kind of 'tricks' in very short functions.
避免在 for 循环中引入变量i。通常我只在非常短的函数中使用这些“技巧”。
Personally I very much dislike 'correcting' parameters inside a function this way. I prefer to catch these by asserts and make sure that the contract is right.
我个人非常不喜欢以这种方式“纠正”函数内部的参数。我更喜欢通过断言来捕捉这些并确保合同是正确的。
回答by rflexor
I usually don't need to assign new values to method parameters.
我通常不需要为方法参数分配新值。
As to best-practices - the warning also avoids confusion when facing code like:
至于最佳实践 - 警告还可以避免在面对以下代码时出现混淆:
public void foo() {
int a = 1;
bar(a);
System.out.println(a);
}
public void bar(int a) {
a++;
}