[복제란?]
복제는 뭔가를 똑같이 만든다는 뜻이다.
데이터 타입을 생성할 때 new를 통해 생성하는 것들은 기본 데이터 타입이 아니고 참조형 또는 참조 데이터 타입이라고 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package org.opentutorials.javatutorials.reference;
public class ReferenceDemo1 {
public static void runValue(){
int a = 1;
int b = a;
b = 2;
System.out.println("runValue, "+a);
}
public static void main(String[] args) {
runValue();
}
}
|
결과
1 |
runValue, 1 |
runValue() 메소드의 내용을 살펴보면 itn 타입의 a 변수가 있는데 int는 기본 데이터 타입이다. 이 a 변수에 1을 담고 b 변수를 생성했는데 역시 기본 데이터 타입인 int로 지정되어 있다.
a를 b에 대입했을 때 b의 값을 2로 바꾸면 a의 값은 어떻게 될 것인가를 확인해보기 위해 System.out.println()을 추가했다.
만약 a에 들어있는 값이 2라면 b의 값이 바뀌었을때 b = a; 에 의해 a의 값도 b의 변화에 따라 1이었다가 2가 된다는 것을 의미한다.
ㅎ하지만 1이 출력된다.
int b = a; 는 a에 담긴 값이 1d을 복제해서 그것을 b 변수에 담은 것이다. b에 담겨있는 값인 1을 2로 바뀌도 a에 담긴, 기존의 1이라는 값의 원본은 바뀌지 않는다는 뜻이다.
[참조]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package org.opentutorials.javatutorials.reference;
class A{
public int id;
A(int id){
this.id = id;
}
}
public class ReferenceDemo1 {
public static void runValue(){
int a = 1;
int b = a;
b = 2;
System.out.println("runValue, "+a);
}
public static void runReference(){
A a = new A(1);
A b = a;
b.id = 2;
System.out.println("runReference, "+a.id);
}
public static void main(String[] args) {
runValue();
runReference();
}
}
|
a 변수는 데이터 타입이 A이고, new를 통해 1을 값으로 전달한다.
a 에는 A클래스의 인스턴스가 저장되며 이 인스턴스의 내부적인 id 값은 1이다. b 변수의 데이터 타입은 A 이고 'b = a;' 를 통해 a를 b에 할당했다.
b 변수에 a를 대입했는데 b 변수에 담긴 인스턴스의 id 값도 2가 된 것이다. new 를 통해 만드는 데이터 타입이 담긴 a 변수는 서로 다르게 동작되고 있음을 보여준다.
결록적으로 기본 데이터 타입이 담긴 a를 b에 할당하면 1이라는 값은 b 변수 안에서 복제된다.
반면 runReference()를 실행하면 우선 A 타입의 변수 a가 생성된다. 이 때 A a = new A(1);가 실행되면 A 클래스의 인스턴스가 변수에 저장되는 것이 아니고 일단 클래스의 인스턴스가 메모리 어딘가에 만들어진다. 변수 a는 해당 인스턴스의 위치 정보를 담고 있다.
b = a;를 실행하면 b 변수에 A 인스턴스가 새로 들어가는 것이 아니고 a 변수가 가리키고 있는 A 인스턴스에 대한 주솟값 (위치 정보)만 복제된다. 그래서 b.id = 2;를 실행하면 A 클래스를 이용해 만든 인스턴스가 가진 id 변수의 값이 2로 변경된다. 결과적으로 a.id를 출력하면 a 변수 역시 앞에서 A 인스턴스를 가리키고 있기 떄문에 해당 인스턴스의 id 값인 2가 출력된다.
이를 참조(reference) 라고 한다. 왜냐하면 a 변수가 구체적인 값을 가지고 있는 것이 아니고 그 구체적인 값인 인스턴스는 메모리 어딘가에 저장돼 있고 변수는 인스턴스를 구분할 수 있는 주솟값만 갖고 있기 때문이다.
변수를 통해 인스턴스에 접근하는 방법을 참조라고 한다.
new를 통해 객체를 만드는 데이터 타입, 즉 기본 데이터 타입이 아닌 데이터 타입은 변수를 만등 경우 그러한 변수는 객체를 직접 저장하는 것이 아니라 그 객체에 대한 참조값만을 갖고 있기 떄문에 a 변수를 통해 인스턴스의 값을 수정하면 그것은 곧 b가 가리키고 있는 인스턴스를 수정한 것과 같은 의미가 되는 것이다.
new를 이용해 인스턴스를 만드는 모든 데이터 타입은 찹조형 또는 참조 자료형 또는 참조 데이터형이라 한다.
참조가 메모리를 훨씬 더 조금 사용하고, 원본의 변화가 모든 참조 데이터형에 반영된다는 특성을 사용한 결과이다. 그래서 어떤 경우에 복제와 참조가 일어나는지 잘 이해한다면 자바를 사용하는 과정에서 겪게 되는 갖가지 혼란에서 중심을 잡기가 훨씬 수월할 것이다.
'생활코딩 > JAVA' 카테고리의 다른 글
생활코딩 - JAVA (Colletions Framework) (0) | 2021.01.15 |
---|---|
생활코딩 - JAVA (제네릭) (0) | 2021.01.15 |
생활코딩 - JAVA (상수와 enum) (0) | 2021.01.10 |
생활코딩 - JAVA (Object 클래스) (0) | 2020.12.31 |
생활코딩 - JAVA (예외 던지기) (0) | 2020.12.30 |