Java淺Copy的一些事

LiDaQian發表於2018-11-16

最近發現了一個現象:用BeanUtils.copyProperties(Object source, Object target)時, 如果source和target中有List物件,然後修改了source的List物件中的元素,發現target的List物件也會跟著變化。

調研了BeanUtils.copyProperties(Object source, Object target)原始碼,發現是通過method.invoke方法來實現屬性的copy的,所以物件的屬性複製都是淺Copy。


於是乎就換了一個種方式來寫:

List<A> source = new ArrayList<>();
source.add(new A());
List<A> copy = new ArrayList<>(source);
複製程式碼

發現居然還是不行!

覺得很奇怪,然後看了ArrayList的構造方法,

public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
複製程式碼

elementData = c.toArray() 這段程式碼還是淺Copy。


思考了一會,難道只能通過遍歷元素,然後新增元素的方式來解決嗎?抱著疑問去Google了下,發現該函式Collections.copy解決了問題,進入其原始碼發現是在遍歷元素然後再新增。。。

總結

  • copy完之後,一般都是直接返回給呼叫方了,一般不會再次運算元據,這樣就不會引發淺Copy的問題。這也是copy的正確用法。

相關文章