해결된 질문
작성
·
43
·
수정됨
0
안녕하세요, 널널한 개발자님!
이번 강의에서 clone(), Arrays.copyOf(), System.arraycopy()가 깊은 복사를 수행한다고 설명해주셨는데, 제가 알고 있는 바로는 이 기능들이 얕은 복사를 수행한다고 알고 있어 의문이 들어 질문드립니다:)
먼저 다음은 강의의 예제를 바탕으로 작성한 코드입니다.
import java.util.Arrays;
public class Test_1 {
public static void main(String[] args) {
int[] array1 = {10, 20, 30, 40, 50};
System.out.println("array1: " + Arrays.toString(array1));
//int[] array2 = array1;
int[] array2 = array1.clone();
//int[] array2 = Arrays.copyOf(array1, array1.length);
//int[] array2 = new int[5];
//System.arraycopy(array1, 0, array2, 0, array1.length);
System.out.println("array2: " + Arrays.toString(array2));
System.out.println();
array1[0] = 100;
System.out.println("array1[0] -> 100");
System.out.println("array1: " + Arrays.toString(array1));
System.out.println("array2: " + Arrays.toString(array2));
System.out.println();
array2[1] = 200;
System.out.println("array2[1] -> 200");
System.out.println("array1: " + Arrays.toString(array1));
System.out.println("array2: " + Arrays.toString(array2));
}
}
위 예시에서 강의에서 설명한 대로 clone(), Arrays.copyOf(), System.arraycopy()가 깊은 복사를 수행한다고 생각할 수 있지만 사실 int[]와 같은 값 타입에서는 이를 깊은 복사보다는 단순한 값 복사로 보는 것이 더 적절하다고 생각이 듭니다.(개인적인 생각입니다!)
다음은 참조 타입을 사용한 코드입니다.
import java.util.Arrays;
public class Test_2 {
public static void main(String[] args) {
Person[] array1 = {
new Person("Hello"),
new Person("Hi"),
};
Person[] array2 = array1.clone();
//Person[] array2 = Arrays.copyOf(array1, array1.length);
//Person[] array2 = new Person[2];
//System.arraycopy(array1, 0, array2, 0, array1.length);
System.out.println(array1[0].name + ", " + array1[1].name);
System.out.println(array2[0].name + ", " + array2[1].name);
System.out.println();
array1[0].name = "Good";
System.out.println("array1[0].name = Good");
System.out.println(array1[0].name + ", " + array1[1].name);
System.out.println(array2[0].name + ", " + array2[1].name);
System.out.println();
array2[1].name = "Nice";
System.out.println("array2[1].name = Nice");
System.out.println(array1[0].name + ", " + array1[1].name);
System.out.println(array2[0].name + ", " + array2[1].name);
}
}
class Person {
String name;
Person(String name) {
this.name = name;
}
}
참조 타입인 Person[] 배열을 사용했을 때 clone(), Arrays.copyOf(), System.arraycopy()가 얕은 복사를 수행하는 것을 확인할 수 있습니다.
clone(), Arrays.copyOf(), System.arraycopy()와 같은 기능들이 값 타입 배열에서 깊은 복사처럼 동작한다고 생각할 수 있겠지만 단순한 값 복사라고 생각이 들며, 참조 타입 배열에서는 확실하게 얕은 복사를 수행합니다.
clone(), Arrays.copyOf(), System.arraycopy()가 값 타입에 대해서만 깊은 복사를 수행한다고 할 수 있는지 이에 대해 좀 더 명확한 설명을 듣고 싶습니다:)
답변 2
1
Java의 참조자는 C언어의 포인터와 일치합니다. 같은 맥락에서 참조 타입을 요소로 갖는 배열은 각 요소가 실제 인스턴스가 아니라 참조자입니다. clone(), Arrays.copyOf(), System.arrarycopy() 메서드는 배열 인스턴스를 하나 더 만들어 값을 복사해주므로 Deep copy가 맞습니다. 그러나 참조형에 대한 배열인 경우 배열 인스턴스가 하나 더 만들어지긴 하지만 참조값 자체를 그대로 복사하므로 참조자가 가리키는 클래스 인스턴스 자체가 둘로 늘어나지는 않습니다. 그런 이유 때문에 기본형에 대한 경우와 참조형에 대한 경우는 분명 차이가 있습니다.
그런데 Part 1 강의는 애초 클래스를 다루지 않습니다. 즉, 질문이 이 수업의 범위를 벗어난 것입니다. 객체 수준으로 넘어가 참조자가 등장한다면 클래스에 대한 참조자를 필드로 갖는 클래스의 깊은 복사 문제도 고민해야 합니다. 참고하시기 바랍니다. 😄
1
안녕하세요, 인프런 AI 인턴입니다. 형씌님!
질문해주신 내용은 Java에서의 배열 복사 방식에 관한 중요한 개념을 잘 지적해주셨습니다. 우선, clone()
, Arrays.copyOf()
, System.arraycopy()
같은 메서드가 복사를 어떻게 수행하는지 짚고 넘어가겠습니다.
얕은 복사 vs 깊은 복사:
Java의 배열 복사 메서드:
clone()
, Arrays.copyOf()
, System.arraycopy()
는 기본적으로 얕은 복사를 수행합니다. 즉, 배열의 요소가 참조 타입일 경우, 각 요소의 참조만 복사되어 실제 객체는 공유됩니다.코드 예제 분석:
int[]
형의 기본 자료형 배열을 복사했는데, 이 경우는 메서드에 관계없이 값 자체가 복사됩니다.Person[]
배열을 복사했으며, 이 경우 각 배열의 요소들이 같은 Person
객체를 참조하게 됩니다. 이로 인해 배열 간의 객체 변경이 서로 영향을 미치게 됩니다.따라서, 귀하의 이해가 맞습니다. Java에서 제공하는 복사 메서드들은 참조 타입 배열에 대해 얕은 복사를 수행하며, 값 타입 배열에 대해서는 ‘누가 봐도’ 값 자체를 복사하게 되므로 얕은 복사와 깊은 복사의 차이가 크게 없음으로 인식될 수 있습니다.
다른 유사한 질문에서 더 많은 정보를 얻고싶으시면, 다음 링크를 확인해보실 수 있습니다:
- 상속과 오지랖의 콜라보 예제에서 clone() 메서드에 대한 문의드립니다
- Deep Copy 부문 관련 질문
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
clone()
,Arrays.copyOf()
,System.arraycopy()
메서드는 '얕은 복사다' 라고 공식처럼 이해하고 있었는데, 복사 대상이 기본형인지 참조형인지에 따라 달라질 수 있다는 점을 새롭게 배워갑니다. 자세한 답변 감사합니다:)