【发布时间】:2012-08-14 17:44:56
【问题描述】:
假设我正在用 Java 编写一个方法 foo(int i)。
由于i 是按值传递的,因此在foo 中更改它是安全的。例如
在 Java 中更改方法的参数是好还是坏?
【问题讨论】:
标签: java pass-by-value
假设我正在用 Java 编写一个方法 foo(int i)。
由于i 是按值传递的,因此在foo 中更改它是安全的。例如
在 Java 中更改方法的参数是好还是坏?
【问题讨论】:
标签: java pass-by-value
这只是个人意见,但我认为这可能会让其他可能想要在该代码后面使用 original 参数值的人感到困惑,并且可能不会注意到它已经被更改.
另外,简单地创建另一个变量并为其分配修改后的值(即int j = i + 1)是很便宜的。
【讨论】:
需要注意的重要一点是i = i + 1; 并没有真正改变 i。它只会更改您本地的 i 副本(换句话说,调用代码中的 i 不会更改)。
基于此,通过遵守the POLS (Principle Of Least Surprise),这是一个可读性和避免代码中出现意外行为的问题。
【讨论】:
i,但不改变作为参数传递的原始值,它不必被称为i,实际上甚至不必是一个变量。跨度>
中性。但许多人认为将方法更改为:
void foo(final int i) {
int j = i + 1; // not change i
...
}
无论哪种方式都可以随意工作。
【讨论】:
取决于上下文。我倾向于“不良做法”,原因有两个:
当它是参考值时会弹出第三个问题。如果您修改参数引用以指向其他对象并更改其状态,则原始 不会 被修改——这可能是也可能不是预期的。如果您创建另一个对参数的引用并更改新引用的状态,则参数的引用将被更改——这也可能是也可能不是预期的。
【讨论】:
a + 1 的含义一样明显。
由于 i 是按值传递的,因此可以安全地更改它
foo()
即使传递对象引用也是绝对安全的,因为它们是本地的:即,为本地引用分配新引用不会对调用代码中的原始引用产生任何影响
这是您的个人选择。但是我不会更改参数值,因为可能会丢失传递给此方法的实际值的跟踪。
【讨论】:
一般来说,这被认为是不好的做法,尽管有些人会忽略它,正如您在其他答案中看到的那样。
对于像原语这样直接按值传入的参数,覆盖原来的变量并没有什么好处。在这种情况下,您应该按照@João 的建议进行复制。
对于 reference 是按值传入的参数(对象),如果修改句柄以指向不同的对象,那真是令人困惑。更重要的是,修改作为参数传递的对象的内容也会修改原始对象。
如果你替换句柄引用的对象,然后修改its的内容,调用者中原始引用所引用的对象不会被替换,但是看代码的人可能会想到它是。
而如果您不替换对象并修改内容,那么调用您的方法的方法可能不会期望这种变化。此类别通常属于与安全相关的不良做法。
【讨论】:
new SomeClass() 评估为引用;字段和方法访问使用引用。这就是“对象不是值”的意思。你不能“传递”一个对象。