返回对象引用的最佳实践
考虑以下代码片段:
class MyClass{
private List myList;
//...
public List getList(){
return myList;
}
}
当 Java 按值传递对象引用时,我的理解是任何调用 getList()
的对象都将获取对 myList
的引用,从而允许它修改 myList
尽管它是私有
。这是正确的吗?
而且,如果它是正确的,我是否应该使用它
return new LinkedList(myList);
来创建副本并传回对副本(而不是原始副本)的引用,以防止未经授权访问 myList
引用的列表?
Consider this code snippet:
class MyClass{
private List myList;
//...
public List getList(){
return myList;
}
}
As Java passes object references by value, my understanding is that any object calling getList()
will obtain a reference to myList
, allowing it to modify myList
despite it being private
. Is that correct?
And, if it is correct, should I be using
return new LinkedList(myList);
to create a copy and pass back a reference to the copy, rather than the original, in order to prevent unauthorised access to the list referenced bymyList
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为将字段设为私有并提供访问器的模式只是为了数据封装。如果您希望某些东西真正私有,请不要为其提供访问器方法!然后,您可以编写其他方法来返回私有数据或其副本的不可变版本。
I think that the pattern of making fields private and providing accessors is simply meant for data encapsulation. If you want something to be truly private, don't give it accessor methods! You can then write other methods that return immutable versions of your private data or copies thereof.
我这样做。更好的是,有时我使用 Collections API 返回不可修改的副本。
如果您不这样做,那么您的推荐人就不是私人的。任何有参考资料的人都可以改变您的私人状态。对于任何可变引用(例如日期)也是如此。
I do that. Better yet, sometimes I return an unmodifiable copy using the Collections API.
If you don't, your reference is not private. Anyone that has a reference can alter your private state. Same holds true for any mutable reference (e.g., Date).
这取决于你想要什么。
您想公开该列表并使其可供人们编辑吗?
还是想让人看,但不修改?
在这种情况下,没有正确或错误的方法。这仅取决于您的设计需求。
It depends on what you want.
Do you want to expose the list and make it so people can edit it?
Or do you want to let people look at it, but not modify it?
There is no right or wrong way in this case. It just depends on your design needs.
在某些情况下,人们可能希望将“原始”列表返回给调用者。但总的来说,我认为这是一种不好的做法,因为它破坏了封装,因此反对面向对象。
如果您必须返回“原始”列表而不是副本,那么 MyClass 的用户应该明确清楚。
There can be some cases when one would want to return the "raw" list to the caller. But in general, i think that it is a bad practice as it breaks the encapsulation and therefore is against OO.
If you must return the "raw" list and not a copy then it should be explicitly clear to the users of MyClass.
是的,它有一个名字......“防御副本”。还建议在接收端进行复印。正如 Tom 所指出的,程序的行为要容易得多预测集合是否不可变。因此,除非有充分的理由,否则应该使用不可变集合。
当 Google Guava 成为 Java 标准库的一部分时(我完全认为它应该) ,这可能会成为首选习惯用法:
并且
这会带来额外的性能优势,因为
copyOf()
方法会检查集合是否已经是不可变集合的实例(instanceof ImmutableList
code>) 如果是,则跳过复制。Yes, and it has a name.. "Defensive copy". Copying at the receiving end is also recommended. As Tom has noted, behavior of the program is much easier to predict if the collection is immutable. So unless you have a very good reason, you should use an immutable collection.
When Google Guava becomes part of the Java standard library (I totally think it should), this would probably become the preferred idiom:
and
This has an added bonus of performance, because the
copyOf()
method checks whether the collection is already an instance of immutable collection (instanceof ImmutableList
) and if so, skips the copying.