在 Java 中更改参数是一种好习惯吗
Posted
技术标签:
【中文标题】在 Java 中更改参数是一种好习惯吗【英文标题】:Is it a good practice to change arguments in Java 【发布时间】:2012-08-14 17:44:56 【问题描述】:假设我正在用 Java 编写一个方法 foo(int i)
。
由于i
是按值传递的,因此在foo
中更改它是安全的。例如
在 Java 中更改方法的参数是好还是坏?
【问题讨论】:
【参考方案1】:这只是个人意见,但我认为这可能会让其他可能想要在该代码后面使用 original 参数值的人感到困惑,并且可能不会注意到它已经被更改.
另外,简单地创建另一个变量并为其分配修改后的值(即int j = i + 1
)是很便宜的。
【讨论】:
我的个人观点与你的不同。不了解您正在更改的方法是不好的。 @CaptainGiraffe 真的。但是恶作剧使理解该方法变得比它必须的更难,并且区分传入和(无论出于何种原因)更改的值有助于理解。 世界上的每一种意见总是个人意见或公司意见:) 这个问题显然是要问普遍共识是什么。那是一个坏主意。由于我的回答中所述的原因。【参考方案2】:需要注意的重要一点是i = i + 1;
并没有真正改变 i。它只会更改您本地的 i
副本(换句话说,调用代码中的 i
不会更改)。
基于此,通过遵守the POLS (Principle Of Least Surprise),这是一个可读性和避免代码中出现意外行为的问题。
【讨论】:
它改变了本地的i
,但不改变作为参数传递的原始值,它不必被称为i
,实际上甚至不必是一个变量。跨度>
【参考方案3】:
中性。但许多人认为将方法更改为:
void foo(final int i)
int j = i + 1; // not change i
...
无论哪种方式都可以随意工作。
【讨论】:
【参考方案4】:取决于上下文。我倾向于“不良做法”,原因有两个:
-
有些人可能会认为原来的值被改变了。
它可能使代码更难推理(通过适当简短的方法缓解)。
当它是参考值时会弹出第三个问题。如果您修改参数引用以指向其他对象并更改其状态,则原始 不会 被修改——这可能是也可能不是预期的。如果您创建另一个对参数的引用并更改新引用的状态,则参数的引用将被更改——这也可能是也可能不是预期的。
【讨论】:
#1 不是一个好的理由。如果他们不知道一个方法使用的是什么参数传递方式,那么他们遇到的问题比误解那个方法更严重,应该在进行更多编码之前先了解这一点。 @delnan 这是一个很好的理由——在可能的情况下应该避免任何混淆,在这种情况下可能会出现这种情况。你可能不同意这个理由,这很好。 好吧,我不同意这个理由。但不是因为我不避免混淆,而是因为我认为对于每个真正了解该语言的人来说,它的含义与a + 1
的含义一样明显。【参考方案5】:
由于 i 是按值传递的,因此可以安全地更改它
foo()
即使传递对象引用也是绝对安全的,因为它们是本地的:即,为本地引用分配新引用不会对调用代码中的原始引用产生任何影响
这是您的个人选择。但是我不会更改参数值,因为可能会丢失传递给此方法的实际值的跟踪。
【讨论】:
真实且重要的是要知道。但是您应该将其写在评论中,而不是答案中。另请注意,OP 从未暗示其他方式。 好的。顺便说一句,OP是什么意思?我是新手:) 不用担心。 OP = Original Post(er),即提出此问题的 Michael。【参考方案6】:一般来说,这被认为是不好的做法,尽管有些人会忽略它,正如您在其他答案中看到的那样。
对于像原语这样直接按值传入的参数,覆盖原来的变量并没有什么好处。在这种情况下,您应该按照@João 的建议进行复制。
对于 reference 是按值传入的参数(对象),如果修改句柄以指向不同的对象,那真是令人困惑。更重要的是,修改作为参数传递的对象的内容也会修改原始对象。
如果你替换句柄引用的对象,然后修改its的内容,调用者中原始引用所引用的对象不会被替换,但是看代码的人可能会想到它是。
而如果您不替换对象并修改内容,那么调用您的方法的方法可能不会期望这种变化。此类别通常属于与安全相关的不良做法。
【讨论】:
Java 中的一切都是按值传递的。对象没有“通过”;对象不是值。 如果我使用按值调用和按引用调用这两个术语,您会感觉更好吗?另外,“对象不是值”是什么意思? 没有。它始终是按值传递(或“按值调用”)。 Java 中唯一的类型是原始类型和引用类型。因此,唯一的值是原语和引用,它们都是按值传递的。与 C++ 不同,你不能有一个变量,其值“是”一个对象。您只能拥有一个变量,其值是指向对象的引用。你对对象所做的一切都必须通过引用来完成——new SomeClass()
评估为引用;字段和方法访问使用引用。这就是“对象不是值”的意思。你不能“传递”一个对象。
是的,我阅读了有关该主题的所有论点,但我仍然认为您选择的短语比有用更令人困惑。我改写了答案,所以如果现在看起来还可以,请告诉我。以上是关于在 Java 中更改参数是一种好习惯吗的主要内容,如果未能解决你的问题,请参考以下文章