[Effective Java] 49. Wrapper class 대신 기본자료형을 사용하라

1 분 소요

모든 기본 자료형(primitive type)에는 이와 대응되는 참조 자료형이 있다.
이를 boxed primitive type 이라고 부른다.

JDK 1.5부터는 autoboxing, auto-unboxing을 지원하게되어 기본 자료형과 이런 참조 자료형의 차이를 희미하게 만든다.

이는 분명 장점이 있지만 실질적인 차이가 있기 때문에 그 차이를 정확히 아는 것이 중요하다.

1. 차이점

  1. 기본 자료형은 값이지만 객체화딘 기본 자료형은 reference 이다.

  2. 기본 자료형에 저장되는 값은 기능적으로 완벽한 값이지만 객체화된 기본 자료형은 값 외에 null 값을 포함할 수 있다.

  3. 기본 자료형이 메모리 사용에서 효율적이다.

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을 참고.

댓글남기기