Home » 레퍼런스 » JAVA » java arrays copyof 메소드를 알아봅시다.

java arrays copyof 메소드를 알아봅시다.

java arrays copyof 메소드는, 원본 배열의 내용을 다른 배열에 복사합니다. 해당 메소드의 설명을 보면 아래와 같이 나와 있습니다.

[그림 1] 함수에 대한 설명

인자로 받는 것은 2개입니다.

  • 원본 배열
  • 복사받을 배열의 크기

인자들을 다른 배열에 복사할 때 원본 데이터의 시작 위치와 종료 위치, 복사 받을 시작 위치와 종료 위치, 크기를 받습니다. 그런데 2개만 받습니다. 이는, 특수 케이스만 커버한다는 의미입니다. Object 배열과 primitive type 배열에 대해 overloading 되어 있습니다. 그러므로, 사용법 차이는 없습니다. 주의해야 할 점은 밑에서 후술하겠습니다.


java arrays copyof 내부 소스 보기

이 메서드의 코드를 보도록 하겠습니다.

[그림 2] 내부 소스 코드

3586번째 줄을 보면, srcPos와 destPost가 0임을 알 수 있습니다. 그리고 5번째 인자는 몇 개의 인자를 복사할 것인지를 나타내는데요. 이로 미루어 보았을 때, 3586번째 줄은 아래와 같은 일을 함을 알 수 있습니다.

  • 원본 배열의 0번째 위치부터 복사합니다.
  • 복사 받을 배열에 0번째 위치부터 차례로 데이터를 넣습니다.
  • original 배열의 크기와, 복사 받을 배열의 길이 중 작은 것의 수만큼 복사합니다.

이게 무슨 소리인지 두 가지 케이스를 보도록 하겠습니다.

[그림 3] 복사 받을 배열이 더 큰 경우

예제 1번을 보겠습니다. 이 예제는 원본 배열의 길이는 10, 복사 받을 배열의 길이는 20입니다. 원본보다 복사 받을 배열이 더 큽니다. 이 경우, 10개의 데이터가 복사됩니다. 그러면 원본의 어디서부터 어디까지, 복제본의 어디서부터 어디까지 복사가 될까요?

ori의 회색으로 표시된 부분부터 10개의 원소가 복사됩니다. dest의 0번째 위치부터요. 제가 회색으로 표시한 부분입니다. 복사해 보겠습니다.

위 그림과 같이 복사됩니다. 원본의 0번째부터 10개의 원소를, 복사본의 0번째부터 복사했기 때문입니다. 실행 결과는 아래와 같습니다.

[그림 4] 예제 1번의 실행 결과

복사 받은 배열의 0번째 원소부터 9번째 원소까지 0, 1, .. , 9 순으로 들어갔습니다. 반대로, 원본이 복사받을 배열보다 크면 어떻게 될까요?

[그림 5] 복사받을 배열이 더 작은 경우

예제 2번은, 원본 배열의 길이가 10이지만, 복사받을 배열의 길이는 5입니다. 더 작습니다. 5와 10 중에 작은 쪽은 5이므로, 원본 배열에서 맨 처음부터 5개의 원소가 복사됩니다.

즉, 위 그림과 같이 복사가 됩니다. 정리를 하자면, java arrays copyof 메서드는 아래와 같이 동작합니다.

  • 복사를 하는 원소의 개수 x는 min(원본 배열의 크기, 복사받을 배열의 크기)이다.
  • 원본의 0번째 위치부터 (앞에서부터) x개만큼 복사된다.
  • 복사받을 배열의 0번째 위치부터 x-1번째 위치까지.

여기까지 정리해 주시면 되겠습니다.


얕은 복사가 되는가? 깊은 복사가 되는가?

그러면, 복사 후에 얕은 복사가 될까요? 깊은 복사가 될까요? 이 문제는 Object를 복사해 보면 됩니다.

[그림 6] 예제 3번의 Obj 클래스

먼저, 예제 3번의 Obj 클래스를 보겠습니다. field로 int 하나를 가지네요. 다음에, setX로 x의 값을 설정할 수 있고, toString으로 x의 값을 출력합니다.

[그림 7] 예제 3의 main 클래스

main 함수에서 copyOf를 호출합니다. ori의 0번째 원소부터 4번째 원소까지 dest에 복사 되었습니다. 그리고 저는 객체 ori[0]의 x값을 7로 설정했습니다. 실행 결과가 어떻게 될까요?

[그림 8] 예제 3의 실행 결과

dest[0]을 출력했는데 7이 나왔습니다. 왜 그럴까요? 참조값이 복사되었기 때문입니다.

java arrays copyof 메소드가 수행되기 전에 ori와 dest는 위와 같았습니다. ori[0]의 참조값이 ref_1인데요. 이 ref_1은 보라색 객체를 가리킵니다. 복사 수행 후에는 어떻게 될까요?

dest[0]에 값 ref_1이 복사되었습니다. 이것의 정체가 무엇인가요? ori[0]의 참조값을 의미합니다. 즉, ori[0]과 dest[0]은 같은 객체를 가리키고 있는 것입니다. 당연하게도 ori[0].setX(7)을 호출한 후에는 아래와 같은 상태가 됩니다.

따라서, dest[0]을 출력할 때 7이 나오게 됩니다. object 배열을 copyof 메소드로 복사했더니 얕은 복사가 된 셈입니다. 그렇기 때문에 2d나 3d array를 deep copy 할 때에는 recursive 등을 이용해서 하는 편입니다. 이 방법은 다음 글에서 언급하도록 하겠습니다.

Leave a Comment

11 + 5 =