자바에는 원시 타입(기본 타입, primitive type) 과 참조 타입(Wrapper 클래스, reference type)이 존재한다.
원시 타입
: int, long, float, double, boolean 등
참조 타입
: Intger, Long, FLoat, Double, Boolean 등
출처 : Autoboxing & Unboxing in Java With Simple Examples [ 2022 ] (softwaretestingo.com)
박싱
: 원시 타입 데이터에 대응하는 Wrapper 클래스로 만드는 동작
언박싱
Wrapper 클래스에서 원시 타입으로 변환
// 박싱
int i = 10;
Intger num = new Integer(i);
// 언박싱
Intger num = new Integer(10);
int i = num.intValue();
참조 : Autoboxing & Unboxing in Java With Simple Examples [ 2022 ] (softwaretestingo.com)
JDK 1.5부터는 자바 컴파일러가 박싱과 언박싱이 필요한 상황에 자동으로 처리를 해준다.
// 오토 박싱
int i = 10;
Integer num = i;
// 오토 언박싱
Integer num = new Integer(10);
int i = num;
또 다른 예시를 보면,
// Wrapper 클래스의 리스트에 원시 타입 할당
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(i); // 오토 박싱
위의 예시에서 Integer 객체가 아닌 원시 값 int를 추가해도 컴파일 시 에러가 나지 않는다.
컴파일러가 오토 박싱
해주기 때문
위의 코드는 런타임 시 아래와 같이 실행된다.
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(Integer.valueOf(i));
오토 박싱과 언박싱이 제공되고 있지만, 컴파일러 내부적으로 추가 연산작업이 거치게 된다.
성능 향상을 위해서 오토 박싱&언박싱이 일어나지 않도록 동일한 타입 연산이 이루어지도록 구현하는 것이 좋다.
오토 박싱 연산
public static void main(String[] args) {
long t = System.currentTimeMillis();
Long sum = 0L;
for (long i = 0; i < 1000000; i++) {
sum += i;
}
System.out.println("실행 시간: " + (System.currentTimeMillis() - t) + " ms");
}
// 실행 시간 : 19 ms
동일 타입 연산
public static void main(String[] args) {
long t = System.currentTimeMillis();
long sum = 0L;
for (long i = 0; i < 1000000; i++) {
sum += i;
}
System.out.println("실행 시간: " + (System.currentTimeMillis() - t) + " ms") ;
}
// 실행 시간 : 4 ms
100만건 기준으로 약 5배의 성능 차이가 난다.
불필요한 오토 캐스팅(박싱&언박싱)을 줄일 필요가 있음.
Autoboxing & Unboxing in Java With Simple Examples [ 2022 ] (softwaretestingo.com)