자바의 참조 변수(Reference Type)

2021. 8. 10. 01:00Programming Language/Java

 

생성된 인스턴스의 참조를 담는 변수

 

 

요약

 

자바는 기본적으로 byte, short, int, long, float, double, char, boolean의 8가지 원시 자료형(Primitive Type) 을 가지고 있다. 참조 자료형(참조 변수)는 이 8가지 자료형 말고 전부 다라고 생각하면 된다. 쉽게 말해, new로 객체를 생성하여 할당하는 모든 변수이다.

 

더 쉽게 말해, C/C++ 의 포인터 변수 역할이라고 생각하면 된다.(값의 직접적인 변경 불가)

 

 


 

 

원리

 

기본적으로 원시 자료형의 경우 호출한 함수 내의 scope를 전제하여 stack에 값이 담기게 된다. 예를 들어,

public class PrimitiveValue {
  public static void main(String args[]) {
    int number = 1;
    int result;
    
    result = plusOne(number);
  }
  
  public static int plusOne(int number) {
    int plused = number + 1;
    return plused;
  }
}

 

 

main에 int형 변수 number, result가 있고, 인자로 넣어준 값을 1 증가시켜 돌려주는 plusOne 함수가 구현되어 있다고 하자. 이 경우, main함수 실행 시 자바 메모리 영역 중 스택 영역은 다음과 같이 변하게 된다.

 

 

이처럼 원시 자료형의 경우 자료 값을 담은 변수는 스택 영역에 위치하게 된다.

한편, 우리가 new 키워드를 사용하여 객체를 생성하면, 이 객체는 힙 영역에 위치하게 된다(가비지 컬렉터가 객체를 제거하기 전까지). 바로 이 힙 영역에 존재하는 객체의 주소(참조)를 담는 변수가 참조 변수이다.

 

참조 변수 자체는 함수의 scope에 전제하여 스택 영역에 위치하였다가(값을 담는 변수이므로), scope가 끝날 시 스택에서 제거된다.

하지만 참조되는 객체 자체는 힙 영역에 위치하여 가비지 컬렉터가 제거하기 전까지는 존재하게 된다.

 

예시로, 다음 코드를 보자.

public class ReferenceValue {
  public static void main(String args[]) {
    String name = new String("Lee Sang Hoon");
    
    String nickName = myNickName();
  }
  
  public static String myNickName() {
    String temp = new String("aree");
    return temp; //temp는 지역 변수이므로, myNickName 함수 종료 시 스택에서 제거됨.
  }
}

 

main 함수에선 String 객체를 생성 후, 그 참조를 담는 name 변수를 생성한다. 또한 myNickName 함수를 호출해 리턴되는 값을 nickName 변수에 담는다. main 함수 실행 시 메모리 영역은 다음과 같이 변화하게 된다.

 

 

장황하게 설명했지만, C/C++ 해본 사람들에겐 참조 변수의 정체에 대해 딱 감이 왔을 것이다.

아 포인터 변수구나!

하지만 C/C++과는 다르게, 포인터 변수 값을 직접 조정하거나 연산하지는 못한다. 선 넘지 마라

 

 


 

 

참고

https://yaboong.github.io/java/2018/05/26/java-memory-management/

http://tcpschool.com/java/java_array_memory

'Programming Language > Java' 카테고리의 다른 글

JVM의 Garbage Collection 과정  (0) 2021.08.20
[String] equals 메서드와 == 연산의 차이  (0) 2021.08.19
자바의 스택 / 프레임 구조  (0) 2021.08.13
자바의 접근 제어자  (0) 2021.08.11
배열  (0) 2021.08.08