본문 바로가기
JAVA

[JAVA] 변수의 기본형 타입(Primitive type)과 참조형 타입(Reference type)

by stonage 2023. 5. 28.

처음 자바를 공부하게 되면 기본형 타입과 참조형 타입에 대해 배우게 된다. 개념 자체는 그리 어렵지 않지만 막연히 사용하다보면 이따금씩 두 타입의 차이점이 헷갈려서 종종 검색해볼 때가 있는데 개인적으로 열람할 용도로 정리할 필요성을 느꼈다.

 

 

 

 

 

기본형 타입(Primitive Type)

논리형(boolean), 문자형(char), 정수형(byte, short, in, long), 실수형(float, double)으로 구성된다. 특징은 아래와 같다.

 

- 기본형 타입은 메모리의 스택(stack)영역에 저장된다.

- 저장 공간에 실제 데이터 값을 가진다. 

- 참조형 타입과 다르게 객체가 아니기 때문에  null 을 가질 수 없다. 

- 산술 연산이 가능하다. 

 

 

 

 

 

참조형 타입(Reference Type)

8가지 기본형 타입을 제외한 나머지 모든 변수 타입이다. 

ex) Integer, Boolean, String, Double과 같은 수나 문자열을 저장하는 객체 및 클래스, 인터 페이스 등의 모든 타입

 

- 기본형 타입과 달리 실제 값은 heap 영역에 저장이 되고 stack 영역에는 실제 값이 저장된 메모리상의 주소가 저장된다. 

- 객체이기 때문에 null 을 가질 수 있다

- 산술 연산이 불가능하다 .

 

 

간단히 말해서 기본형 변수는 stack영역에 실제 값을 직접 저장하고 그 값을 사용할 때에도 실제 값을 그대로 사용한다. 반면 참조형 변수는 실제 값이 저장된 주소를 가리키고 있으며 그 값을 사용할 때에는 해당 주소로 이동하여 값을 가져온다.

그런데 참조형 타입의 경우 산술 연산이 안된다고 하였다. 그런데 아래와 같은 경우에도 오류가 나지 않는 것을 알 수 있다. 

Integer a = 1;
Integer b = 2;

System.out.println("a + b = " + (a + b));

출력

a + b = 3

 

또한 a와 b는 Integer라는 객체 형태이지만 new Integer() 가 아닌 1, 2와 같은 int 형 기본 타입으로 초기화가 되었다. 어떻게 이런게 가능할까? 그것은 JDK 1.5버전 이후 추가된 AutoBoxing과 AutoUnBoxing 기능 때문이다.

 

 

 

 

 

AutoBoxing, AutoUnBoxing

 

해당 개념에 대해 알기 전에 래퍼 클래스(Wrapper Class)에 대해서 간단하게 짚고 넘어가겠다.

래퍼 클래스란 기본 타입의 데이터를 객체로 포장해주는 클래스를 말한다. 만약 특정 메소드의 파라미터가 Integer형 객체 타입만 요구한다면 int 자료형 데이터를 사용할 수는 없다. 바로 이런 경우 기본형 타입의 데이터를 객체로 변환시켜주는 클래스를 래퍼 클래스라고 부른다. 8개의 기본형 타입은 각각 상응하는 래퍼 클래스가 존재한다. 

기본타입(primitive type)  래퍼클래스(wrapper class)
byte Byte
char Character
int Integer
float Float
double Double
boolean Boolean
long Long
short Short

 

기본형 타입 변수를 참조형 변수인 래퍼클래스로 포장하는 것을 Boxing, 그 반대 과정은 UnBoxing이라고 부른다.

 

Boxing : 기본형 타입 -> 참조형 타입

UnBoxing : 참조형 타입 -> 기본형 타입

 

이 과정은 사용자가 별도 작업을 하지 않아도 JDK 1.5 이후 부터는 자동으로 변환시켜주기 때문에 위에서 Integer a = 1 과 같이 기본형 타입 데이터가 객체형 변수인 Integer a 에 할당이 되는 것처럼 보여지는 것이다. 사용자가 모르는 사이에 JDK는 Boxing을 하였다. 또한 Integer형 변수 a와 b의 연산 역시 JDK 가 a, b를 각각 UnBoxing한 다음 연산을 하기 때문에 에러가 발생하지 않는다.