객체화된 기본 자료형 대신 기본 자료형을 이용하라
자바의 자료형 시스템은 두 부분으로 나뉜다.
하나는 int, double, boolean 등의 기본 자료형(primitive type)
다른 하나는 String, List 등의 참조 자료형(reference type) 이다.
모든 기본 자료형에는 대응 되는 참조 자료형이 있는데, 이를 객체화된 기본 자료형(boxed primitive type)이라 부른다. (Integer, Double .. )
※릴리스 1.5부터 자동 객체화(autoboxing)과 자동 비객체화(auto-unboxing)이 언어의 일부가 됨
기본 자료형과 객체화된 자료형 사이에는 세 가지 큰 차이점이 있다.
첫번째, 기본 자료형은 값만 가지지만 객체화된 기본 자료형은 값 외에도 신원(identity)을 가진다는 것
두번째, 기본 자료형에 저장되는 값은 전부 기능적으로 완전한 값(fully functional value)이지만, 객체화된 기본 자료형에 저장되는 값에는 그 이외에도 아무 기능도 없는 값, 즉 null이 하나 있다는 것
세번째, 기본 자료형은 시간이나 공간 요구량 측면에서 일반적으로 객체 표현형보다 효율적이라는 것
기본자료형과 객체 표현형 사이의 차이를 무시하는 경우 발생하는 문제
예1)
Comparator<Integer> naturalOrder = new Comparator<Integer>(){
public int compare(Integer first, Integer second){
return first < second ? -1 : (first == second ? 0 : 1);
}
};
위 코드는 심각한 문제가 있는데, nautreOrder.compare(new Integer(42), new Integer(42)) 테스트 해보면 알 수 있다.
Integer라는 객체는 42라는 동일한 값을 나타내므로 0이 나와야 정상이지만, 반환되는 값은 1이다.
이유는 무엇일까?
표현식 first == second에서 문제점이 나타난다.
연산자 == 는 객체 참조를 통해 두 객체의 신원을 비교하기 때문에(identity comparison) first와 second가 다른 Integer 객체인 경우 flase를 반환하는 것이다.
객체화된 기본 자료형에 == 연산자를 사용하는 것은 거의 항상 오류라고 봐야한다.
inf f = first;
int s = second; 코드를 넣어 Auto-unboxing을 사용하여 두 변수를 비교하면 정상동작하는 것을 확인 할 수 있다.
예2)
public class Unbelievable{
static Integer i;
public static void main(String[] args){
if(i == 42){
System.out.println("Unbelievable");
}
}
}
위 코드를 실행하면 i == 42 를 계산 할때 NullPointException이 발생된다.
위의 프로그램이 (i == 42)를 계산할 때 비교되는 것은 Integer 객체와 int 값이다.
거의 모든 경우에서, 기본 자료형과 객체화된 기본 자료형을 한 연산 안에 엮어 놓으면 객체화된 기본 자료형은 자동으로 기본자료형으로 변환된다.
그렇기 때문에 위 코드는 i 가 null 인 객체참조를 기본 자료형으로 변환하려 시도하여 NullPointException이 발생하게 된다.
계속해서 객체화와 비객체화를 반복하면 성능이 느려질 수있음
그렇다면 객체화된 기본 자료형은 언제 사용할까?
첫 번째, 컬렉션의 요소, 키, 값으로 사용할 때다. 컬렉션에는 기본 자료형을 넣을 수 없으므로 객체화된 자료형을 써야 한다.
두 번째, 형인자 자료형(parameterized type)의 형인자로는 객체화된 기본 자료형을 써야한다.
'프로그래밍 노트 > Effective 시리즈' 카테고리의 다른 글
익명 클래스보다는 람다를 사용하라. (0) | 2019.12.26 |
---|---|
규칙4. 객체 생성을 막을 때는 private 생성자를 사용하라 (0) | 2018.11.29 |
규칙3. private 생성자나 enum 자료형은 싱글턴 패턴을 따르도록 설계하라 (0) | 2018.11.26 |
규칙1. 생성자 대신 정적 팩터리 메서드를 사용할 수 없는지 생각해 보라 (0) | 2018.11.26 |
규칙48. 정확한 답이 필요하다면 float와 double은 피하라 (0) | 2018.11.14 |