[Effective Java] 49. Wrapper class 대신 기본자료형을 사용하라
모든 기본 자료형(primitive type)에는 이와 대응되는 참조 자료형이 있다.
이를 boxed primitive type 이라고 부른다.
JDK 1.5부터는 autoboxing, auto-unboxing을 지원하게되어 기본 자료형과 이런 참조 자료형의 차이를 희미하게 만든다.
이는 분명 장점이 있지만 실질적인 차이가 있기 때문에 그 차이를 정확히 아는 것이 중요하다.
1. 차이점
-
기본 자료형은 값이지만 객체화딘 기본 자료형은 reference 이다.
-
기본 자료형에 저장되는 값은 기능적으로 완벽한 값이지만 객체화된 기본 자료형은 값 외에 null 값을 포함할 수 있다.
-
기본 자료형이 메모리 사용에서 효율적이다.
2. 잘못 사용할 수 있는 예
2.1. 예제 1
Comparator<Integer> naturalOrder = new Comparator<Integer>() {
public int compare(Integer first, Integer second) {
return first < second ? -1 : (first == second ? 0 : 1);
}
}
위 예제는 정확히 정렬되어 정상 동작하는 것처럼 보인다.
하지만 동일한 값을 비교하는데 버그가 있다. 정렬이 정상적으로 보이는 이유는 같은 값에서만 버그가 있어 티가 안났기 때문이다.
naturalOrder.compare(new Integer(42), new Integer(42));
예를 들어 이 결과는 같은 값이기 때문에 0이 리턴되어야 하지만 1을 리턴한다.
문제가 되는 부분은 first == second
로 연산자 == 는 객체의 값이 아니라 reference를 비교한다.
객체화된 기본 자료형에서 == 연산자를 사용하는 것은 항상 버그라고 봐야 한다.
2.2. 예제 2
static Integer i;
public static void main(String[] ar) {
if ( i == 42 ) {
System.out.println("HAHAHA");
}
}
위 예는 NullPointException이 발생한다.
문제가 되는 부분은 i == 42
이다. 객체화된 기본 자료형과 기본 자료형을 한 연산안에 엮어두면 auto-unboxing이 일어나 자동으로 기본 자료형으로 변환을 한다.
하지만 현재 i는 null이기 때문에 NullPointException이 발생하는 것이다.
언제 autoboxing과 auto-unboxing이 일어나는가..
2.3. 예제 3
5. 불필요한 객체 생성 지향 포스팅에서 다뤘던 예이다. 불필요한 객체 생성때문에 성능이 매우 떨어진다.
public static void main(String[] args) {
Long sum = 0L;
for(long i=0; i<Integer.MAX_VALUE; i++) {
sum += i;
}
}
3. 객체화된 기본 자료형을 사용하는 경우
3.1. Collection의 요소나 Key로 사용할 때
컬렉션에는 기본 자료형을 넣을수 없기 때문이다.
즉, HashSet<int>
와 같은 표현은 불가능하고 HashSet<Integer>
와 같이 사용할 수 있다.
3.2. 리플렉션을 통해 메서드를 호출할 때
규칙 53을 참고.
댓글남기기