[JAVA] AutoBoxing과 Unboxing

henu·2024년 4월 15일

자바에는 크게 2가지 데이터 타입이 존재한다

Primitive Data(원시 타입)

  • boolean, char, byte, short, int, long, float, double
  • 가벼운 데이터
  • 스택 메모리에 위치

Object Data(객체)

  • 무거운 데이터
  • 실제 데이터는 힙메모리에 공유하고 래퍼런스만 스택메모리에 위치

Wrapper Class

  • Primitive data를 객체로 다루기 위해서 사용하는 Class
  • Primitieve data를 Object Data화 시킨 Class
  • 모든 기본형 타입(primitive type)은 값을 갖는 객체 생성 가능, 이런 객체를 포장객체라고 부른다. 이유는 기본타입의 값을 내부에 두고 포장하기 때문이다. wrapper 클래스로 감싸고 있는 기본 타입 값은 외부에서 변경이 불가능하다. 값을 바꾸고 싶다면 새로운 포장 객체를 만들어야한다.
  • wrapper class는 java.lang 패키지에 포함되어 있다.

wrapper class 사용 이유

  • 기본 자료형의 값을 굳이 wrapper class로 포장하는 이유는 제네릭, 자료구조, 매개변수 등 기본 자료형이 아닌 래퍼런스 타입을 필요로 하는 경우가 많고 메서드를 갖고 있어 다양하게 활용이 가능하다.
  • 인스턴스를 생성하여 상속 및 재사용이 가능하다.
  • 문자열(String)을 기본 타입 값으로 변환할 때
    • parse + 기본타입명메서드(문자열)
    • ex) Integer.parseInt(문자열), Boolean.parseBoolean(문자열)

wrapper class 종류

wrapper class 종류

wrapper class 구조도

  • 모든 wrapper class의 부모는 Object이다.
  • 내부적으로 숫자를 다루는 wrapper class의 부모 클래스는 Number class이다.
    wrapper class 구조도

auto boxing

  • Primitive Data에서 Wrapper Class로 자동으로 변환되는 것
  • 가벼운 데이터를 무거운 데이터에 넣기
  • 컴파일러가 Primitive Data를 Object Data로 자동변환 하는 것
  • 기본타입의 값을 포장객체로 만드는 과정
  • wrapper class에 기본 자료형의 데이터 대입

auto unboxing

  • Wrapper Class에서 primitive Data로 자동으로 변환되는 것
  • 컴파일러가 Object Data를 Primitive Data로 자동변환 하는 것
  • 무거운 데이터를 가벼운 데이터에 넣기
  • 포장객체에서 기본타입의 값을 얻어내는 과정
  • 기본 자료형에 wrapper 객체 대입
Integer num = 17; // auto boxing
int n = num; // auto unboxing
int a = 10;
Integer b = a; // auto boxing;
int c = b; // auto unboxing;

알고리즘 문제를 풀다가 auto unboxing이 안되는 경우가 있어 자료를 찾아보고 정리하게 되었다.

Integer a = 127;
Integer b = 127;

System.out.println(a == b);

다음 출력값은 true다.

컴파일러가 자동으로 a와 b에 Integer.valueOf(127)로 바꿔서 auto boxing해서 넣어준다.

 @HotSpotIntrinsicCandidate
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

어떤 primitive 값 i를 auto boxing 할 때, IntegerCache.low <= i <= IntegerCache.high에 속할 경우, IntegerCache에서 Integer 객체를 반환해주고 있는 것을 알 수 있다.

이때 내부적으로 같은 값을 보관하고 있기 때문에 동일한 객체를 반환하게 된다.

반대로 이 범위 내에 속하지 못하는 경우 new Integer(i)로 새로운 객체를 만들어서 auto boxing한다.

이때 IntegerCache.lowIntegerCache.high의 기본값은 -128127이다.

따라서 ==과 같은 비교연산자를 사용해서 Integer 값을 비교했을 경우 -128 ~ 127 사이의 숫자일 경우 정상적으로 작동하지만 범위 외의 숫자인 경우 false가 나온다.

원시타입이 아닌 wrapper class를 비교해야할 경우 equals로 비교하는 것이 안전하다.

profile
주니어 백엔드 개발자입니다

1개의 댓글