얕 은 복사의 ArrayList 구조 함수 원본 분석 / System. arraycopy ()

8260 단어 자바
지난주 에 어떤 친구 가 저 에 게 Array List 의 구조 함수 Array List (Collection extends E > c) 가 얕 은 복사 인지 깊 은 복사 인지 물 었 습 니 다. 그 때 는 단번에 반응 하지 않 고 단원 테스트 를 써 서 검 증 했 습 니 다. 결 과 는 얕 은 복사 입 니 다. 코드 는 다음 과 같 습 니 다. (얕 은 복사 원 리 는 이 글 을 참고 할 수 있 습 니 다.)
    public void testAr(){
        List beanDemos = new ArrayList<>();
        BeanDemo beanDemo = new BeanDemo();
        beanDemo.setName("test1");
        beanDemos.add(beanDemo);
        List beanDemoList = new ArrayList<>(beanDemos);
        beanDemo.setName("test2");
        System.out.println(beanDemoList.get(0).getName());
        //    test2
    }

이제 소스 코드 를 깊이 연구 해 보 자. 왜 Array List (Collection extends E > c) 구조 함수 가 얕 은 복사 인지.ArrayList 구조 함수 원본 은 다음 과 같 습 니 다.
    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    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;
        }
    }

구조 함 수 는 먼저 집합 형식의 매개 변 수 를 배열 (ArrayList 바 텀 실현 은 배열 이 고 LinkedList 바 텀 실현 은 목록) 으로 바 꾼 다음 에 Arrays. copyof () 방법 을 호출 했 습 니 다. 전 삼 은 원시 배열 과 복사 배열 의 길이 입 니 다. copyof () 는 원시 배열 의 사본 을 가 져 와 서 절단 되 거나 null 로 채 워 서 지정 한 길 이 를 되 돌려 줍 니 다.원본 코드 는 다음 과 같 습 니 다. 이 단계 에서 얕 은 복사 인지 깊 은 복사 인지 알 수 없습니다.
public static  T[] copyOf(U[] original, int newLength, Class extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

copyof () 방법 에 서 는 주로 System. arraycopy () 방법 을 사용 하여 목록 복사 를 실현 하고 System. arraycopy () 를 내 려 다 보 았 는데 이것 은 원생 native 함수 (native 방법 은 자바 로 이 루어 진 것 이 아니 라) 라 는 것 을 알 게 되 었 습 니 다. 저 는 이 원생 방법의 주석 을 자세히 읽 을 수 밖 에 없 었 습 니 다. 글 의 맨 아래 를 참조 하고 주석 내용 이 비교적 길 었 습 니 다.그러나 첫 번 째 주석 은 array copy () 방법 을 직접 알려 주 었 습 니 다. 복사 하 는 것 은 배열 의 참조 주소 이기 때문에 간단 한 복사 에 속 합 니 다. A subsequence of array components are copied from the source array referenced by src to the destination array referenced by dest.
종합: ArrayList 의 구조 함수 ArrayList (Collection extends E > c) 는 얕 은 복사 입 니 다.
/**
     * Copies an array from the specified source array, beginning at the
     * specified position, to the specified position of the destination array.
     * A subsequence of array components are copied from the source
     * array referenced by src to the destination array
     * referenced by dest. The number of components copied is
     * equal to the length argument. The components at
     * positions srcPos through
     * srcPos+length-1 in the source array are copied into
     * positions destPos through
     * destPos+length-1, respectively, of the destination
     * array.
     * 

* If the src and dest arguments refer to the * same array object, then the copying is performed as if the * components at positions srcPos through * srcPos+length-1 were first copied to a temporary * array with length components and then the contents of * the temporary array were copied into positions * destPos through destPos+length-1 of the * destination array. *

* If dest is null, then a * NullPointerException is thrown. *

* If src is null, then a * NullPointerException is thrown and the destination * array is not modified. *

* Otherwise, if any of the following is true, an * ArrayStoreException is thrown and the destination is * not modified: *

    *
  • The src argument refers to an object that is not an * array. *
  • The dest argument refers to an object that is not an * array. *
  • The src argument and dest argument refer * to arrays whose component types are different primitive types. *
  • The src argument refers to an array with a primitive * component type and the dest argument refers to an array * with a reference component type. *
  • The src argument refers to an array with a reference * component type and the dest argument refers to an array * with a primitive component type. *
*

* Otherwise, if any of the following is true, an * IndexOutOfBoundsException is * thrown and the destination is not modified: *

    *
  • The srcPos argument is negative. *
  • The destPos argument is negative. *
  • The length argument is negative. *
  • srcPos+length is greater than * src.length, the length of the source array. *
  • destPos+length is greater than * dest.length, the length of the destination array. *
*

* Otherwise, if any actual component of the source array from * position srcPos through * srcPos+length-1 cannot be converted to the component * type of the destination array by assignment conversion, an * ArrayStoreException is thrown. In this case, let * k be the smallest nonnegative integer less than * length such that src[srcPos+k] * cannot be converted to the component type of the destination * array; when the exception is thrown, source array components from * positions srcPos through * srcPos+k-1 * will already have been copied to destination array positions * destPos through * destPos+k-1 and no other * positions of the destination array will have been modified. * (Because of the restrictions already itemized, this * paragraph effectively applies only to the situation where both * arrays have component types that are reference types.) * * @param src the source array. * @param srcPos starting position in the source array. * @param dest the destination array. * @param destPos starting position in the destination data. * @param length the number of array elements to be copied. * @exception IndexOutOfBoundsException if copying would cause * access of data outside array bounds. * @exception ArrayStoreException if an element in the src * array could not be stored into the dest array * because of a type mismatch. * @exception NullPointerException if either src or * dest is null. */ public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);


좋은 웹페이지 즐겨찾기