简体   繁体   English

将对象的引用传递给 java 中的方法是一种好习惯吗?

[英]Is it good practice to pass references of objects to methods in java?

Is it acceptable style to pass an object reference to a method (as a parameter) and modify the object in that method, or should that method return a reference to a new object?将 object 引用传递给方法(作为参数)并在该方法中修改 object 是否可以接受,或者该方法是否应该返回对新 object 的引用? What is the best practice and why?最佳做法是什么,为什么?

By default, when you pass objects to a method, you are doing so by reference.默认情况下,当您将对象传递给方法时,您是通过引用进行的。 If objects should be immutable, design them as such (eg String ).如果对象应该是不可变的,那么设计它们(例如String )。

I would say its best practice to modify the this object of the method.我想说它的最佳实践是修改this object 的方法。 It is better not to modify the objects passed as arguments even if they are mutable.最好不要修改作为 arguments 传递的对象,即使它们是可变的。 If you going to return an object for chaining, its usually best to return this;如果您要返回 object 进行链接,通常最好return this; rather than an argument.而不是争论。

Avoid "broad" parameters (referential transparency / clarity of intent)避免“宽泛”的参数(参考透明度/意图清晰)

I would go a step further than the accepted answer and say (in general) do not pass objects (or object references, strictly speaking) to methods as parameters.我会 go 比接受的答案更进一步,并说(通常)不要将对象(或严格来说 object 引用)作为参数传递给方法。

In practice what happens is you end up with unclear code as I will attempt to illustrate in the following all-too-familiar example people working in the industry see:在实践中,您最终会得到不清楚的代码,因为我将尝试在以下业内工作人员看到的非常熟悉的示例中进行说明:

Example例子

Compare this:比较一下:

Employee emp = ...;
Validator.checkIsEligibleForPPCTP(emp);

with this:有了这个:

Employee emp = ...;
Validator.checkIsEligibleForPPCTP(emp.getEmailAddress());

What the hell is a PPCTP ? PPCTP到底是什么? You need domain knowledge of whatever a PPCTP is.您需要任何 PPCTP 的领域知识。 All you know is that it will look at the employee object and do something.你所知道的是它会查看员工 object 并做一些事情。

If, on the other hand, you avoid passing the whole object but just pass what is actually relevant, readers know more of what is happening without having to examine the definition of checkIsEligibleForPPCTP .另一方面,如果您避免传递整个 object 而只是传递实际相关的内容,则读者无需检查checkIsEligibleForPPCTP的定义即可了解更多正在发生的事情。 I bet you can more easily imagine what that validation method does by virtue of the fact we are passing an email address to it (in fact, even if you are slightly wrong in your imagination, a narrative is often good enough when it comes to code comprehension).我敢打赌,您可以更容易地想象该验证方法的作用,因为我们将 email 地址传递给它(事实上,即使您的想象有点错误,在代码方面,叙述通常就足够了理解)。


Further thoughts进一步的想法

(Weak) Counterargument (弱)反驳

But what if we in future we need another field from this broad object?但是,如果我们将来需要这个广泛的 object 的另一个领域怎么办? You'll have to modify the signature.您必须修改签名。

Oh how terrible, I wouldn't want to saddle someone else with that, no one else is smart as me (ok changing signatures requires some care, but there are better solutions than just passing the universe into a simple method).哦,太可怕了,我不想让其他人为此背负,没有其他人像我一样聪明(好吧,更改签名需要一些小心,但有更好的解决方案,而不是仅仅将宇宙传递给一个简单的方法)。

This tweet is the answer to "prefactoring" / programming "for the future" (and it applies to method-level design):这条推文是“预分解”/“面向未来”编程的答案(它适用于方法级设计):

The wrong abstraction is far more damaging than no abstraction at all.错误的抽象比根本没有抽象更具破坏性。 Waiting trumps guessing every time.等待胜过猜测。

Clarifications澄清

Yes I know that a java.lang.String is an object.是的,我知道java.lang.String是 object。 And often you have to pass java.util.Collection .通常你必须通过java.util.Collection These are different to "custom objects" because:这些与“自定义对象”不同,因为:

  • Strings are immutable字符串是不可变的
  • Collections can (and should) be immutable copies when passed as parameters Collections 在作为参数传递时可以(并且应该)是不可变的副本
    • if they are not, your code will be harder to understand because your method becomes stateful / has side effects (ie it is an impure function)如果不是,您的代码将更难理解,因为您的方法变得有状态/有副作用(即它是一个不纯的函数)

If you insist on passing an object, at least make it immutable.如果你坚持要传递一个 object,至少让它不可变。 But if your emp object is instead a TLOYDEmployee , again you are handicapped in your effort to understand the intent of the code and all you have to go on is shared understanding of the meaning of business jargon (the use-reuse paradox).但是,如果您的 emp object 是TLOYDEmployee ,那么您在理解代码意图方面的努力就会受到阻碍,而您对 go 所要做的就是对业务术语含义的共同理解(使用-重用悖论)。

Should once pass the object reference to methods and modify them in methods or have the >methods return new references?应该将 object 引用传递给方法并在方法中修改它们还是让 >methods 返回新的引用?

Its of no use.. why to return??它没有用..为什么要返回?

It should return mostly in the case of immutable objects.它应该主要在不可变对象的情况下返回。

For example例如

bigDecimalOb3 = bigDecimalOb1.add(bigDecimalOb2);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM