Skip to content

Latest commit

 

History

History
101 lines (69 loc) · 4.14 KB

박싱된 기본 타입보다는 기본 타입을 사용하라.md

File metadata and controls

101 lines (69 loc) · 4.14 KB

학습 배경

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을 박싱된 기본 타입으로 선언하여 느려졌다. 박싱과 언박싱이 반복되어 느려진다

  1. 저장 공간 원시타입은 스택영역에, 래퍼클래스는 힙 영역에 저장된다. 따라서 배열등에서 지역성을 이용한 캐시 히트를 높이려면 원시타입이 낫다.

사용하지 말아야하는 이유

사례 1

잘못 구현된 비교자

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);
};

사례 2

    public class PlayTime {

        private final Integer playTime;


        public PlayTime(Integer playTime) {
            validate(playTime);
            this.playTime = playTime;
        }

        private void validate(Integer playTime) {
            if (playTime < 0) {
                throw new IllegalArgumentException("0이상이어야함");
            }
        }
    }

playTime < 0를 검사할 때 NullPointerException을 던진다. 초기값이 null이기 때문이다.

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

사용해야 할 때

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

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

  • db와 연동할 때. null 값 처리가 용이하기 때문에 SQL과 연동할 경우에 처리를 원활하게 할 수 있다. We recommend that you declare consistently-named identifier attributes on persistent classes and that you use a nullable (i.e., non-primitive) type - Hibernate ORM docs