Item61. 박싱된 기본 타입보다는 기본 타입을 사용하라!
자바의 데이터 타입
- 기본타입
- int, double, boolean 등
- 참조타입
- String, List 등
- 박싱된 기본타입
- 각각의 기본 타입에 대응하는 참조 타입
- 오토박싱과 오토언박싱 덕분에 두 타입의 구분에 크게 신경쓰지 않아도 되지만, 분명한 차이가 있으니 어떤 타입을 사용할지 주의해야 한다.
기본타입과 박싱된 기본타입의 차이
- 기본 타입은 값만 가지고 있으나, 박싱된 기본타입은 값에 더해 식별성(identiry)이란 속성을 갖는다.
- 값이 같더라도 서로 equals 하지 않을 수 있다.
- 기본 타입의 값은 언제나 유효하나, 박싱된 기본타입은 유효하지 않은 값인 null이 허용된다.
- 기본 타입이 박싱된 기본타입보다 시간과 메모리 사용면에서 더 효율적이다.
예제
Integer
1
Comprator<Integer> naturalOrder = (i, j) -> (i < j) ? -1 : (i == j ? 0 : 1);
- 오름차순으로 정렬하고 있다. 이는 잘못 구현된 비교자이다.
- Integer 타입에서 ==을 사용하면 참조된 객체를 비교하게 된다. 이 때문에 값이 같더라도 false를 반환할 수 있다.
- Integer 타입에선 compare 메서드를 사용해 값을 비교할 수 있다.
1
2
3
4
5
Comprator<Integer> naturalOrder = (i, j) -> {
int number1 = i;
int number2 = j;
return (number1 < number2) ? -1 : (number1 == number2 ? 0 : 1);
}
- 박싱된 기본타입을 기본 타입으로 오토언박싱 후 비교하도록 수정함으로써 문제를 해결했다.
기본 타입과 박싱된 기본 타입을 혼용한 연산
- 기본 타입과 박싱된 기본 타입을 혼용한 연산에서는 박싱된 기본 타입이 자동으로 언박싱된다.
- null 참조를 언박싱하면 NullPointerException이 발생한다.
성능
- 박싱과 언박싱이 반복해서 일어나면 불필요한 객체 생성이 반복되기 때문에 성능이 저하된다.
- 기본 타입과 박싱된 기본 타입의 차이를 고려하자.
박싱된 기본 타입의 사용
- 박싱된 기본타입은 언제 사용해야 하는가?
- 컬렉션의 원소, 키, 값으로 사용한다.
- 컬렉션은 기본 타입을 담을 수 없는 태생적 한계가 있으니 박싱된 기본타입 사용이 강제된다.
- 매개변수화 타입이나 매개변수화 메서드의 타입 매개변수로는 박생된 기본타입을 써야 한다.
- 자바는 타입 매개변수로 기본 타입을 지원하지 않는다.
- 리플렉션을 통해 메서드를 호출하는 경우에도 박싱된 기본타입을 사용해야 한다.
- 컬렉션의 원소, 키, 값으로 사용한다.
핵심 정리
- 기본 타입과 박싱된 기본 타입 중 하나를 선택해야 한다면 가능하면 기본 타입을 사용하라.
- 기본 타입은 간단하고 빠르다.
- 박싱된 기본 타입 사용 시 주의를 기울이자.
- 오토박싱은 박싱된 기본타입 사용 시의 불편함을 해소해주지만, 그 위험까지 없애주지는 않는다.
- == 연산자로 비교하면 안 된다.
- == 으로 비교하면 식별성 비교가 이뤄지기 때문에, 우리가 원하는 값 비교 결과를 얻는 것이 아니다.
- 같은 연산에서 기본타입과 박싱된 기본타입을 혼용 시, 언박싱이 이뤄지는데 이 과정에서 NullPointerException이 발생할 수 있다.
- 기본 타입을 박싱하는 작업은 필요 없는 객체 생성을 늘리는 부작용이 있다.
Comments powered by Disqus.