V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
c4f36e5766583218
V2EX  ›  Java

CopyOnWriteArrayList: The array, accessed only via getArray/setArray

  •  
  •   c4f36e5766583218 · 2019-04-14 13:40:26 +08:00 · 2045 次点击
    这是一个创建于 2079 天前的主题,其中的信息可能已经有所发展或是发生改变。
        /** The array, accessed only via getArray/setArray. */
        private transient volatile Object[] array;
    
        /**
         * Gets the array.  Non-private so as to also be accessible
         * from CopyOnWriteArraySet class.
         */
        final Object[] getArray() {
            return array;
        }
    
        /**
         * Sets the array.
         */
        final void setArray(Object[] a) {
            array = a;
        }
    

    https://monkeysayhi.github.io/2017/10/24/%E6%BA%90%E7%A0%81%7C%E5%B9%B6%E5%8F%91%E4%B8%80%E6%9E%9D%E8%8A%B1%E4%B9%8BCopyOnWriteArrayList/

    getArray()方法则直接返回成员变量 array。
    我没明白为什么要再封装一层,而不是直接访问。
    

    使用 getArray/setArray 方法有什么特殊含义吗?

    12 条回复    2019-05-16 16:06:03 +08:00
    hujianxin
        1
    hujianxin  
       2019-04-14 13:45:49 +08:00
    因为一个是 list,一个是 array,楼主是来搞笑的吗?
    cxtrinityy
        2
    cxtrinityy  
       2019-04-14 13:57:06 +08:00
    你得理解 CopyOnWriteArrayList 实现 free lock 的原理,你 set/add element 的时候,实现如同名字所说,会把内部实际存储数据的 array copy 到新数组,这样你在多线程操作的时候才不会出现 ConcurrentModificationException,因为修改的是新的 array,修改完后通过 setArray 取代原来的 array
    c4f36e5766583218
        3
    c4f36e5766583218  
    OP
       2019-04-14 14:32:11 +08:00
    @hujianxin #1 我是说 getArray/setArray 内部源码也就一句话,为什么要封装成一个方法来使用呢?
    你比如说 CopyOnWriteArrayList#toArray()这个方法
    ```
    public Object[] toArray() {
    Object[] elements = getArray();
    return Arrays.copyOf(elements, elements.length);
    }
    ```
    为什么不写成
    ```
    public Object[] toArray() {
    Object[] elements = array;
    return Arrays.copyOf(elements, elements.length);
    }
    ```
    wwqgtxx
        4
    wwqgtxx  
       2019-04-14 14:33:01 +08:00 via iPhone
    java 的惯例吧,参见 java bean 的习惯,类本身不暴露内部成员,访问全部通过 setter 和 getter
    c4f36e5766583218
        5
    c4f36e5766583218  
    OP
       2019-04-14 14:34:09 +08:00
    @cxtrinityy #2 你说的是 CopyOnWriteArrayList 的实现原理,和我想问的貌似不知道影响不影响,参考下 3 楼回复。
    MoHen9
        6
    MoHen9  
       2019-04-14 14:41:57 +08:00 via Android
    应该是习惯,这么做可以统一控制 array 数组的访问,假如代码要扩展,比如说加锁,就可以在 get 方法中加,而不是每个使用到 array 变量的地方加锁。
    cxtrinityy
        7
    cxtrinityy  
       2019-04-14 14:46:37 +08:00
    这个只是基础的 getter/setter 模式吧,
    beidounanxizi
        8
    beidounanxizi  
       2019-04-14 15:32:10 +08:00
    恭喜你 你说的没错 😄 作者有点中二吧 我迄今为止无法沟通 setter getter 带来的工程意义
    c4f36e5766583218
        9
    c4f36e5766583218  
    OP
       2019-04-14 15:58:14 +08:00
    @beidounanxizi #8 你是说 java bean 无法理解吗?这个感觉说的蛮好的: https://www.zhihu.com/question/19773379/answer/31625054
    hujianxin
        10
    hujianxin  
       2019-04-14 16:04:59 +08:00
    刚才没理解楼主的意思,抱歉。

    关于这个问题,查到网上只有一个 stackoerflow 问题聊到了,https://stackoverflow.com/questions/47030394/why-copyonwritearraylist-use-getarray-to-access-an-array-reference

    不过也没有说出个所以然来。不过看到这两个方法都是 final 的,首先排除利用子类重写的方法这个理由。

    至于有没有内存模型相关的考虑,我也没有看出来。
    hujianxin
        11
    hujianxin  
       2019-04-14 16:06:36 +08:00
    应该也不是 Doug Lea 的特殊癖好,因为他写的别的 class 也有很多直接访问私有属性的例子。
    c4f36e5766583218
        12
    c4f36e5766583218  
    OP
       2019-05-16 16:06:03 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2622 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:40 · PVG 18:40 · LAX 02:40 · JFK 05:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.