Gae Ko's Blog

[JAVA] 참조? 본문

프로그래밍언어/JAVA

[JAVA] 참조?

Gae Ko 2018. 3. 17. 22:27

"배열도 여러 개의 참조를 가질 수 있다."

"리스트를 배열 참조 aa에 할당하면 단지 그 익명 배열 객체의 메모리 주소가 참조 변수 aa로 복사되기만 한다. "


참조..... 할당.... 헷갈린다!!! 자바에서 '메모리', '객체', '참조변수'라는 기본 개념을 정확히 알고자 찾아보았다. 


java에서는 기본데이터형을 제외한 모든 데이터 타입은 참조 데이터형(참조 자료형)이라고 부른다. 기본 데이터형은 '복제'되지만 참조데이터형은 '참조'된다. new를 사용해서 객체를 만드는 모든 데이터 타입이 참조 데이터형이라고 생각해도 된다. (단 String은 제외) 


즉 변수에 담겨있는 데이터가 기본형이면 그 안에는 실제 데이터가 들어있고, 기본형이 아니면 변수 안에는 데이터에 대한 참조 방법이 들어있다고 할 수 있다. 


new연산자와 생성자를 이용하여 메모리 할당. // 꼭 생성자를 호출하여야함

new연산자는 객체의 메모리를 생성시켜주는 역할을 담당.

new연산자와 생성자를 이용해서 메모리를 생성했다면 하나의 객체로써 사용할 수 있음. 

C++에서는 new를 이용해서 메모리를 생성했다면 직접적으로 주소 그 자체를 넘겨준다. 그래서 주소를 저장하기 위한 포인터 변수를 이용해 주소를 관리한다. (사용자가 직접 주소를 핸들링 가능)

그러나 자바에서는 주소를 바로 주지 않는다. 클래스로 만든 데이터 타입으로 변수와 메모리를 생성했을 때 주소를 찾아보기는 힘들다. 자바에서는 객체의 주소대신 참조값이라는 것을 할당받게 된다. 그렇기 때문에 자바에서의 객체변수를 참조변수(reference variable)라고 말한다. 


Sun s1 = new Sun();

Sun s2 = new Sun();


변수를 선언하고 new연산자와 생성자를 사용하여 메모리 할당.

메모리가 생성되면 내부의 인덱스 테이블(index table)에서 주소를 맵핑하는 참조값을 하나씩 만든다. 그래서 만들어진 참조값은 참조변수 s1과 s2에 할당된다. 


참조값(해시코드)는 가상머신에서 자동으로 생성되며, 객체를 구분하기 위한 유일한 key값이 된다.


System.out.println(s1);

System.out.println(s2); // 객체변수 출력


위는 각 객체의 참조값을 출력하는 코드이다.

객체변수가 주소를 가지는 것이 아닌 주소에 연결되어 있는 참조값을 가지게 된다. 이런 의미에서 자바의 객체변수를 참조변수라고 하며 참조변수에는 참조값이라는 정수값이 들어있다.


다시 말하자면 객체를 만들면 자바를 실행시켜주는 시스템 내에서 객체의 주소에 연결된 숫자를 하나 던져준다. 이 숫자는 객체가 받아 챙기게 되며 객체는 이 숫자(참조값)를 이용해서 해당 객체의 메모리에 값을 할당하거나 메소드를 호출할 수 있다.


s1.apple =10; 


위 코드는 다음과 같이 의미한다.

- s1에는 참조값이 할당되어있다.

- s1의 참조값과 연결된 주소를 검색하기 위해서는 자바 시스템 내부의 인덱스 테이블을 검색한다.

- s1의 참조값에 연결된 주소를 인덱스 테이블에서 찾았다면 해당 메모리에 apple의 자리를 찾는다. 그리고 그 자리에 10을 할당한다.


참조변수끼리의 할당


s3 = s1 하면 뭐가 복사되는 걸까? 이것은 참조값이 복사된다. s1에는 참조값이 들어있기 때문에 s1의 참조값이 s3으로 복사되는 것이다. 결국 똑같은 메모리를 가리키고 있는 것이다. 

즉, Sun s3 = s1; 하면 새로운 메모리를 생성한 게 아니라 s1의 참조값을 이용하여 하나의 메모리를 두 참조변수가 가리키게되는 것이다.


참조값끼리 아무리 복사를 하더라도 객체내부의 메모리까지 복사는 이루어지지 않는다. 이러한 이유에서 자바에서는 값에 의한 호출만 존재한다. 그래서 클론(clone)이라는 기법을 이용해 연결된 메모리까지 복사하는 기법이 있다. 



[출처] http://robyncloud.tistory.com

 


'프로그래밍언어 > JAVA' 카테고리의 다른 글

[JAVA] 정적변수와 정적메소드 (static)  (0) 2018.03.12
[JAVA] 생성자(constructor)  (0) 2018.03.12
[JAVA] this 와 this()  (0) 2018.03.12
11월 21일  (0) 2017.11.22
main 메소드  (0) 2017.11.14