본문 바로가기
생활코딩/JAVA

생활코딩 - JAVA (참조)

by Love of fate 2021. 1. 10.
728x90
반응형

[복제란?]

복제는 뭔가를 똑같이 만든다는 뜻이다.

데이터 타입을 생성할 때 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를 이용해 인스턴스를 만드는 모든 데이터 타입은 찹조형 또는 참조 자료형 또는 참조 데이터형이라 한다. 

참조가 메모리를 훨씬 더 조금 사용하고, 원본의 변화가 모든 참조 데이터형에 반영된다는 특성을 사용한 결과이다. 그래서 어떤 경우에 복제와 참조가 일어나는지 잘 이해한다면 자바를 사용하는 과정에서 겪게 되는 갖가지 혼란에서 중심을 잡기가 훨씬 수월할 것이다. 

 

 

728x90
반응형