자동차 경주 미션을 진행하는 도중 최대로 멀리간 position의 값을 구하기 위해 아래와 같은 method를 사용하였다.
private int getFarthestPosition() {
return cars.stream()
.map(Car::getPosition)
.max(Integer::compare)
.orElse(-1);
}
리뷰어께서 이에 대해 불필요한 unboxing과 boxing 과정이 있다고 피드백을 주셨다.
unboxing과 boxing을 대충 무엇인지는 알고있었지만 이번 기회에 제대로 알아보기로 했다!
래퍼 클래스(Wrapper class)
자바의 자료형은 기본 타입(Primitive type)과 참조형 타입(Reference Type) 으로 나뉜다.
- 기본 타입 : int, long, float, double, char, boolean 등
- 참조 타입 : class, interface, array, enum 등
래퍼 클래스는 8개의 기본 타입에 해당되는 데이터를 객체로 포장해주는 클래스이다.
래퍼 클래스가 필요한 이유는 무엇일까? 즉, 데이터를 객체로 포장해주는 행위가 왜 필요할까?
메서드의 파라미터로 객체 타입을 요구하거나, Generics를 사용하는 경우 등 기본 타입의 데이터를 사용할 수 없으므로, 객체로 변환한 후 작업을 수행해야 한다.
박싱(Boxing) & 언박싱(Unboxing)
박싱 : 기본 타입의 데이터를 래퍼 클래스로 만드는 행위
언박싱 : 래퍼 클래스에서 기본 타입으로 만드는 행위
//박싱
int i = 0;
Integer wrappedI = new Integer(i);
double d = 0;
Double wrappedD = new Double(d);
//언박싱
Integer wrappedI = new Integer(0);
int i = wrappedI.intValue();
Double wrappedD = new Double(0);
double d = wrappedD.doubleValue();
오토 박싱 & 언박싱
jdk 1.5 이전엔 기본 타입과 래퍼 클래스의 구분이 명확했지만, 1.5 이후엔 자바 컴파일러가 박싱과 언박싱이 필요한 상황에 자동으로 처리해준다. 이를 오토 박싱 & 언박싱이라고 한다.
//jdk 1.5 이전
List<Integer> list = new ArrayList<>();
list.add(new Integer(0)); // 필수적으로 boxing을 해줘야 함
//jdk 1.5 이후
List<Integer> list = new ArrayList<>();
list.add(0); // 0이 integer형의 기본 타입이지만 자바 컴파일러에 의해 자동으로 Integer 객체로 boxing이 됨
그렇다면, 리뷰어분께선 왜 이러한 unboxing과 boxing 과정이 불필요하다고 하셨을까?
그 이유는 성능에 있다. 오토 박싱과 언박싱은 편리하지만 그만큼 내부적으로 추가 연산 작업이 필요하다.
동일한 타입 연산을 했을 때와 비교하면 100만건 기준 5배의 성능 차이가 난다고 한다.
따라서, 개발할 때 불필요한 오토 캐스팅을 지양해야겠다.
참고
'우아한테크코스 > prolog' 카테고리의 다른 글
스프링은 왜 쓸까? (feat. 끝장토론) (0) | 2022.05.09 |
---|---|
Servlet이란? (2) | 2022.04.29 |
함수형 인터페이스의 위력(?) (0) | 2022.03.04 |