생활코딩에 arrays.Copyof 메서드에 대한 질문이 올라왔었습니다. 그런 의미에서 이 함수를 간단하게 보도록 하겠습니다. 먼저, 메서드 이름에서 보면 알 수 있다시피, 배열을 복사하는 함수입니다. 배열의 내용을 다른 array로 복사합니다.

 

 


 여기까지만 짚고, copyOf의 내용을 간략하게 보도록 하겠습니다. 먼저 primitive 타입이 아닌 배열을 copyOf를 할 때에는 3180번째 줄에 있는 친구가 호출이 됩니다.

 

 

 그러면, 3181번째의 리턴문이 수행이 될 듯 싶네요. 따라 들어가 보겠습니다.

 

 

 그러면 위 메소드가 수행이 되는데요. 3항 연산자, arraycopy, 리턴문. 이렇게 3개의 문장으로 구성이 되어 있습니다. 이게 어떻게 수행이 되는지 정확히 모르겠으니, main 클래스를 작성해서 디버깅을 해 보도록 하겠습니다.

 

 

 먼저, 18번째 줄에, Object 배열을 복사합니다. 그리고 19번째 줄에서는 Dog 배열인 org를 복사합니다. 이 둘이 무슨 차이가 있는지 보면 될 듯 싶습니다.

 

 

 먼저, 18번째 줄에 있는 CopyOf 메소드를 호출했을 때, 어떻게 함수를 호출하는지 들어가 보겠습니다.

 

 

 arg0이 Object[3]입니다.

 

 

 그러면, 어떻게 수행이 될까요? F5를 계속 눌러보면, Array.newInstance(...)가 호출되지 않음을 알 수 있어요. 이는 arg2로 들어온 타입이 Object[]이기 때문입니다. 그렇기 때문에, Object 배열만 새로 생성합니다.

 

 

 반면에 19번째 줄의 배열 복사 메서드를 호출하면 이야기가 달라집니다. 이 때에는newInstance 안에 들어와 있음을 알 수 있는데요.

 

 

 여기서, newArray 메소드를 또 호출합니다. componentType은 여러 가지 정보를 담고 있는데.. 

 

 

 여기서, Class<T> (Dog)라는 정보가 중요한 듯 보였습니다.

 

 

 사실, 3212번째 줄을 자세히 보셨다면, newType의 getComponentType의 리턴값을 newInstance의 1번째 인자로 넣는다는 것을 알 수 있는데요. getComponentType의 선언 부분을 보면, class<?>를 리턴한다는 것을 알 수 있어요. 이것은, component type of array. 즉 배열의 요소 타입을 리턴하는데요. Dog[]가 newType이였다면, Dog를 리턴할 거에요.

 

 

 이 과정까지를 간단하게 도식화 시켜보면 위와 같습니다. 이 Dog라는 정보가, 3212번째 줄에 있는 newInstance를 호출할 때 중요한 정보로 쓰인 셈입니다. 이러한 일련의 과정을 거친 다음에, arrayCopy를 하고, 결과 배열을 돌려줍니다.

 

 

 원본과 복사본 배열은 id 값을 다르게 가지고 있어요. 그렇지만, 각 요소들의 id 값은 같아요. deep copy가 아닌 shallow copy가 되었다는 이야기입니다. 이 부분은 챙겨 가셔야 할 중요한 포인트 중 하나입니다. 코드를 분석하다가 나온 <T>라던지 <?>과 같은 문법은 나중에 다시 언급을 하도록 하겠습니다.

 

 


 그러면, 기본 타입인 경우에는 어떨까요? 기본 타입이란, byte, short, int, long, char, float, double, boolean 이렇게 8개의 타입을 의미합니다. 수행 알고리즘은 모두 동일하니 이 중 하나인 int형 1차원 배열을 복사할 때 상황을 보도록 하겠습니다.

 

 

 우리는 배열 요소 타입이 int인 것을 알고 있어요. 그렇기 때문에, 먼저 3284번째 줄에서, 새로운 int형 배열을 선언합니다. 다음에, arrayCopy로 새 배열에 기존에 있었던 배열의 내용들을 복사합니다. 그리고 새 배열을 돌려줍니다. 내용이 객체값이 아니고, 그냥 value 값 자체이기 때문에 얕은 복사에 의한 문제가 생기지 않습니다.