오토 박싱이란
자바의 변수에는 크게 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 |