返回对象引用的最佳实践

发布于 2024-09-08 16:35:43 字数 451 浏览 5 评论 0原文

考虑以下代码片段:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱你不解释 2024-09-15 16:35:44

我认为将字段设为私有并提供访问器的模式只是为了数据封装。如果您希望某些东西真正私有,请不要为其提供访问器方法!然后,您可以编写其他方法来返回私有数据或其副本的不可变版本。

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.

冷月断魂刀 2024-09-15 16:35:43

我这样做。更好的是,有时我使用 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).

我也只是我 2024-09-15 16:35:43

这取决于你想要什么。

您想公开该列表并使其可供人们编辑吗?

还是想让人看,但不修改?

在这种情况下,没有正确或错误的方法。这仅取决于您的设计需求。

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.

盛夏尉蓝 2024-09-15 16:35:43

在某些情况下,人们可能希望将“原始”列表返回给调用者。但总的来说,我认为这是一种不好的做法,因为它破坏了封装,因此反对面向对象。
如果您必须返回“原始”列表而不是副本,那么 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.

分开我的手 2024-09-15 16:35:43

是的,它有一个名字......“防御副本”。还建议在接收端进行复印。正如 Tom 所指出的,程序的行为要容易得多预测集合是否不可变。因此,除非有充分的理由,否则应该使用不可变集合。

Google Guava 成为 Java 标准库的一部分时(我完全认为它应该) ,这可能会成为首选习惯用法:

return ImmutableList.copyOf(someList);

并且

void (List someList){
    someList = ImmutableList.copyOf(someList);

这会带来额外的性能优势,因为 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:

return ImmutableList.copyOf(someList);

and

void (List someList){
    someList = ImmutableList.copyOf(someList);

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文