加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

访问Java中的私有Collection字段

发布时间:2020-12-15 02:04:33 所属栏目:Java 来源:网络整理
导读:我的一个类有一个包含Set的字段.此字段仅在构造函数中填充,然后由其他类读取.最初我有这样的事情: public class Foo { public final SetString myItems; public Foo(CollectionString theirItems) { this.myItems = new LinkedHashSetString(theirItems); }
我的一个类有一个包含Set的字段.此字段仅在构造函数中填充,然后由其他类读取.最初我有这样的事情:

public class Foo {
    public final Set<String> myItems;
    public Foo(Collection<String> theirItems) {
        this.myItems = new LinkedHashSet<String>(theirItems);
    }
}

但这违背了OO最佳实践,myItems应该是私有的,并且只能通过setter和getter访问.所以我把它改成了:

public class Foo {
    private final Set<String> myItems;
    public Foo(Collection<String> theirItems) {
        this.myItems = new LinkedHashSet<String>(theirItems);
    }
    public Set<String> getItems() {
        return myItems;
    }
}

现在myItems是私有的,但是调用getItems()的人仍然可以随意添加/删除项目,这与我之前的情况基本相同. (我实际上并不关心有人改变项目内容,这更像是一个理论问题)

所以我改变了getItems()来返回一个数组:

public String[] getItems() {
    return myItems.toArray(new String[myItems.size()]);
}

现在我的物品真的很私密.不幸的是,我知道读取这些项目的对象实际上想要使用Set,因此必须将数组转换回来.我还可以返回myItems的副本:

public Set<String> getItems() {
    return new LinkedHashSet<String>(myItems);
}

这为调用者提供了他们想要的内容,但在每次访问时都创建了一个新的Set.

在这样的情况下你做了什么 – 不惜一切代价保护隐私,接受原始结构的转换/复制,或者牺牲对集合内容的控制并依赖负责的呼叫者?

解决方法

将不可修改的视图返回到您的集合:

public Set<String> getItems() {
    return Collections.unmodifiableSet(myItems);
}

请注意,这意味着如果调用者挂起到返回的集合,则仍会看到您对该集合所做的任何更改.如果你不想那样,你就得制作副本……没有(简单的)方法. (理论上,您可以制作一个不可修改的副本,并返回对同一副本的引用,直到您下次进行更改,但这会变得混乱.)

一个重点是记录您选择的任何内容,以便呼叫者不会得到任何令人讨厌的意外.在许多方面,我认为这实际上是大多数应用程序中最重要的事情,其中??调用者实际上并不是恶意的.只要很清楚效果会是什么,在大多数情况下防守并不是那么重要.当然,如果您的来电者可能是一些不值得信任的代码,并且您的设置对于安全性等至关重要,那么您处于不同的情况.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读