[이펙티브 자바] 아이템 61. 박싱된 기본 타입보다는 기본 타입을 사용하라

June·2022년 3월 16일
0

[이펙티브자바]

목록 보기
55/72

학습 배경

PlayTime

public class PlayTime {
    private Integer playTime;

    public PlayTime(Integer playTime) {
        if (playTime < MIN_PLAY_TIME) {
    ...

boxing 타입으로 받는 이유가 있을까요?

차이점

기본 타입과 박싱된 기본 타입은 차이가 있다.

  1. 박싱된 기본 타입은 값에 더해 식별성을 가진다. 그래서 박싱된 기본 타입의 두 인스턴스는 값이 같아도 서로 다르다고 식별될 수 있다.

위의 코드는 통과가 된다. 왜냐하면 Integer 클래스에서 내부적으로 valueOf로 정적 팩토리 메서드를 호출하면 -128 ~ 127까지 캐싱되어 있기 때문이다.

따라서 캐싱 범위를 넘어서거나 new로 생성할 경우 주소 값이 달라져서 통과하지 못한다.

  1. 기본 타입의 값은 언제나 유효하나, 박싱된 기본 타입은 유효하지 않은 값, 즉 null을 가질 수 있다.
  1. 기본 타입이 시간과 메모리면에서 더 효율적이다.

    sum을 박싱된 기본 타입으로 선언하여 느려졌다. 박싱과 언박싱이 반복되어 느려진다

사용하지 말아야하는 이유

잘못 구현된 비교자

Comparator<Integer> naturalOrder = 
    (i, j) -> (i < j) ? -1 : (i == j ? 0 : 1);

naturlOder.compare(new Integer(42), new Integer(42))의 값을 출력해보면 0을 출력해야하지만 1을 출력한다.

이유는 첫 번째 검사는 잘 통과하는데 i==j에서 식병성을 검사하게되어 false가 나오기 때문이다. 박싱된 기본 타입에 == 연산자를 사용하면 오류가 일어난다.

수정된 비교자

Comparator<Integer> naturalOrder = (iBoxed, jBoxed) -> {
    int i = iBoxed, j = jBoxed;
    return i < j ? -1 : (i == j ? 0 : 1);
};

박싱된 타입을 기본 타입 정수로 저장한 다음 비교를 수행하면된다.

public class Unbelievable {
    static Integer i;
    
    public static void main(String[] args) {
        if (i == 42)
            System.out.println("믿을 수 없군!");
    }
}

i == 42를 검사할 때 NullPointerException을 던진다. 초기값이 null이기 때문이다.

기본 타입과 박싱된 기본 타입을 혼용한 연산에서는 박싱된 기본 타입의 박싱이 자동으로 풀린다. 그리고 null 참조를 언박싱하면 NullPointerException이 발생한다.

사용해야 할 때

컬렉션의 원소, 키 값. 매개변수화 타입 이나 매개변수화 메서드의 타입 매개변수.

리플렉션(아이템 65)를 통해 메서드를 호출할 때도.

null 값 처리가 용이하기 때문에 SQL과 연동할 경우에 처리를 원활하게 할 수 있다.
DB에서 자료형이 정수형이지만 null 값이 필요한 경우 VO에서 Integer를 사용할 수 있음.

0개의 댓글