개발자의 길

[Java] Boxing 과 Unboxing

토아드 2024. 1. 22. 00:34
반응형

 Java 에서는 원시 타입과 참조 타입이라는 개념이 있다. 원시 타입은 int, long, char 등의 가장 기본적인 숫자, 문자등을 저장하는 타입이고, 참조 타입은 Integer, String, Object 등이 있다. 원시 타입은 메모리에 할당된 변수에 '값' 이 바로 들어가 있는 경우를 말하고, 참조 타입은 메모리에 할당된 변수에 '메모리 주소'가 들어가 있어서, 해당 메모리 주소를 한번 더 참조해서 '값' 을 찾아야 한다.


 Boxing 과 Unboxing 은 주로 이러한 원시 타입과 참조 타입간의 변환 가정을 말한다.

 

Boxing :  원시 타입 -> 참조 타입으로의 변환

int 를 Integer 로 변환. long 을 Long 으로 변환, char 를 Char 로 변환

 

Unboxing : 참조 타입 -> 원시 타입으로의 변환

 Integer 를 int 로 변환, Long 을 long 으로 변환, Char 를 char 로 변환 

 

 얼핏 보면 int -> Integer, long -> Long, char -> Char 로의 원시 타입의 변환을 Boxing 과 Unboxing 이라고 이해할 수도 있겠지만, 참조 타입은 Object 로부터 파생된 모든 타입을 뜻한다. 단순히 원시 타입들을 객체로 변화하는 과정 또한 박싱이라고 할 수 있겠다.

 

그렇다면 이런 개념은 왜 알아둬야 할까? 

 

이러한 Boxing 과 Unboxing 과정에서 리소스를 소모하기 때문이다. 메모리를 할당받고, 해당 메모리에 참조 변수형의 값을 넣고, 그 안에 원시 변수형의 '값'을 넣어야 하는 과정을 거쳐야 하기 때문에, 성능이 중요한 코드에서는 이러한 것들을 신경써줘야 하기 때문이다.

 

간단하게 아래 코드를 실행해 보면, 실제 성능 차이가 얼마나 나는지 알수 있다.

 

예제 코드

long currentTimeMillis = System.currentTimeMillis();

Integer sum = 0;
for (int i = 0; i < 100000000; i++) {
    sum += i;  // 여기서 auto-boxing이 일어남
}
System.out.println(System.currentTimeMillis() - currentTimeMillis);

currentTimeMillis = System.currentTimeMillis();
int sum2 = 0;
for (int i = 0; i < 100000000; i++) {
    sum2 += i;  // boxing이 일어나지 않음
}
System.out.println(System.currentTimeMillis() - currentTimeMillis);

 

출력 결과

839
36

 

실행 환경에 따라서 차이는 있겠으나 거의 23배 가까이 차이가 나고 있다.

 

사실 이러한 박싱과 언박싱 개념은 Java 에만 국한된 게 아니라, 값 타입 사용을 허용하는 프로그래밍 언어에서 보일 수 있다. 대표적으로 C#이 있다.

반응형