본문 바로가기
Programming Language/Java

오토박싱, 오토박싱의 문제점과 해결방법

by Ahngyuho 2024. 11. 28.

오토 박싱이란

자바의 변수에는 크게 2 종류가 있는데 하나는 참조형이고 다른 하나는 기본형입니다.
기본형은 숫자, 불리언, 부동소수점 수와 같은 기초적인 값(단순 비트열의 나열)을 의미하고  
참조형은 객체를 참조할 수 있는 값을 의미합니다.  

자바에서는 이런 기본형을 참조형으로 다뤄야 할 때 래퍼 클래스라는 것을 제공합니다.  
기본형         참조형  
int     ->      Integer  
long    ->      Long  
byte    ->      Byte  
char    ->      Character  
short   ->      Short  
double  ->      Double  
boolean ->      Boolean  
float   ->      Float

 

List<Integer> list = new ArrayList<>();
    for(int i=0;i<100000;i++){
        list.add(i);
    }
    
    list.stream().reduce(0,Integer::sum);

 

위 코드를 보시면 제네릭의 형식이 Integer 임에도 불구하고
list.add(i); -> i 라는 기본형을 넣어주었음에도 어떤 컴파일 오류도 보여주고 있지 않습니다.  
이건 자바 5에서부터 등장한 오토박싱이라는 기능 덕분입니다.  
컴파일러가 기본형을 참조형으로 감싸는 코드를 대신 넣어주기 때문에 문제가 발생하지 않습니다.  

그런데 위 코드는 조금 문제가 있습니다.  
프로그래머는 컴파일러가 기본형을 참조형으로 박싱해주기 때문에 편하지만  
성능상에 문제가 발생할 수 있습니다. 

 

startTime = System.currentTimeMillis();
        List<Integer> list = new ArrayList<>();
        for(int i=0;i<1000000;i++){
        list.add(i);
        }
        endTime = System.currentTimeMillis();

        System.out.println(endTime - startTime + "ms");

 

결과
46ms

list.add(i) 할 때 i 는 기본형인데 list 는 제네릭 때문에 Integer 를 원소로 받을 수 있습니다.  
여기서 i 를 Integer 타입으로 자동으로 래핑되고 이걸 오토 박싱 이라고 합니다.  
그런데 이 오토 박싱 과정에서 새로운 객체가 생성되고, 가비지 컬렉터가 발생할 수 있습니다.  

해결방법 - stream 을 이용하자

IntStream.Builder intBuilder = IntStream.builder();
    startTime = System.currentTimeMillis();
    for(int i=0;i<1000000;i++){
        intBuilder.add(i);
    }
    IntStream indexes = intBuilder.build();
    endTime = System.currentTimeMillis();

    IntStream indexes = intBuilder.build();
    System.out.println(indexes.sum());

 

결과
24ms

IntStream 을 이용해서 기본형만을 다룰 수 있도록 해주면 오토박싱을 피할 수 있습니다!  

 

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

쓰레드  (0) 2025.01.07
자바의 형 변환 (Type Casting)  (1) 2024.12.04
Java Start  (0) 2024.06.18
JVM Execution - 자바 코드가 기계어로 번역되기까지  (2) 2023.08.27
Java reflection API  (0) 2023.08.19