본문 바로가기
카테고리 없음

자바(Java)의 박싱과 언박싱(Boxing & Unboxing), 오토박싱과 오토 언박싱(Auto Boxing & Auto Unboxing) 그리고 래퍼 클래스(Wrapper Class)

by 왕 달팽이 2019. 4. 19.
반응형

자바는 int, long, boolean 같은 변수의 기본 자료형(Primitive Type)을 제공한다. 하지만 이런 기본자료형은 컬렉션(Collection)이나 지네릭(Generic)에서 제한적으로 사용가능하다. 따라서 자바는 각 기본 자료형에 대응되는 래퍼 클래스(Wrapper Class) 제공하고 있다.

 

자바 변수의 기본형에 대응되는 래퍼 클래스(Wrapper Class)는 다음과 같다.

 

기본 자료형(Primitive Type) 래퍼 클래스(Wrapper Class)
boolean Boolean
short Short
int Integer
long Long
float Float
double Double
char Character
byte Byte

 

변수의 기본 자료형 이름의 첫 번째 글자만 대문자로 바꾸면 된다고 이해하면 쉽다. 자바에서는 이 래퍼 클래스를 이용해서 기본 자료형을 담는 래퍼 클래스를 만들게 된다.

 

박싱(Boxing)과 언박싱(Unboxing)

자바에서 박싱(Boxing)은 기본 자료형의 데이터를 대응되는 래퍼 클래스로 만드는 동작을 의미한다. 마치 박스에 기본 자료형을 담는 행위를 생각하면 쉽다.

 

각 자료형별 박싱 동작은 다음 코드를 생각하면 된다.

public class Boxing {
    public static void main(String[] args) {
        
        int i = 10;
        Integer wI = new Integer(a); // int Boxing 동작
        
        double d = 3.14;
        Double wD = new Double(d); // double Boxing 동작
        
        boolean b = true;
        Boolean wB = new Boolean(b); // boolean Boxing 동작
    }
}

이처럼 기본 자료형을 생성자(Constructor)에 넘겨주어 대응되는 래퍼 클래스를 생성하는 동작을 '박싱(Boxing)'이라고 한다. 

 

반다로 '언박싱(Unboxing)' 동작은 래퍼 클래스에서 기본 자료형으로의 변환을 의미한다. 

 

public class Boxing {
    public static void main(String[] args) {
        
        Integer wI = new Integer(10);
        int i = wI.intValue();     // Integer Unboxing 동작
        
        Double wD = new Double(3.14);
        double d = wD.doubleValue(); // Double Unboxing 동작
        
        Boolean wB = new Boolean(true);
        boolean b = wB.booleanValue(); // Boolean Unboxing 동작
    }
}

 

래퍼 클래스에 담겨있는 값을 기본 자료형으로 바꾸는 작업이 언박싱이다. 마치 박스에 포장되어 있는 기본 자료형 값을 박스에서 꺼내는 동작을 생각하면 된다.

 

오토박싱(Auto boxing)과 오토 언박싱(Auto unboxing)

명시적으로 기본 자료형을 래퍼클래스로 박싱하고 언박싱하는 동작은 크게 어렵지 않다. 다만 이러한 기본자료형과 래퍼 클래스간의 변환이 묵시적(Implicit)으로 일어나는 경우가 있다. 자바의 특정버전(JDK 1.5)부터는 자바 언어에서 래퍼 클래스와 기본 자료형 사이의 변환을 자동으로 해주는 동작이 추가되었다. 이를 오토 박싱(Auto Boxing)과 오토 언박싱(Auto Unboxing)이라고 한다. 

 

다음 예를 살펴보자.

 

public class WrapperEx04 {
    public static void main(String[] args) {
        int i = 10;
        Integer wI = i;    // Auto boxing
        int i1 = wI;       // Auto unboxing
        
        double d = 3.14;
        Double wD = d;     // Auto boxing
        double d1 = wD;    // Auto unboxing
        
        boolean b = true;
        Boolean wB = b;    // Auto boxing
        boolean b1 = wB;   // Auto unboxing
    }
}

 

int 형 변수에 10이라는 값을 대입한 다음, 이를 Integer 래퍼 클래스에 할당했다. 원래는 int라는 기본 자료형을 Integer 객체를 참조하는 변수에 할당할 수 없다.

Integer wI = new Integer(10);  // 명시적 박싱
Integer wI1 = 10;              // 오토 박싱

하지만 JDK 1.5 버전부터는 위 두 구문이 같은 의미를 갖게 된다. 언어가 자동으로 박싱을 해준다하여 오토박싱이라고 부른다.

 

오토 언박싱도 마찬가지다.

Integer wI = new Integer(10);
int i1 = wI.intValue(); // 언박싱
int i2 = wI; // 오토 언박싱

10이라는 정수가 담긴 래퍼 클래스를 i1 변수에 언박싱했다. i2 변수에는 오토 언박싱되어 역시 10이라는 값이 담긴다. 

 

래퍼 클래스의 연산

C++과 다르게 자바는 연산자를 오버로딩할 수 없다. 그렇다면 다음 코드는 어떻게 동작할까?

 

Integer i1 = new Integer(10);
Integer i2 = new Integer(20);

Integer i3 = i1 + i2; // 동작할까?

 

두 개의 래퍼 클래스인 i1과 i2를 '+' 연산자로 연결하면 어떻게 될까? 원래 래퍼 클래스도 객체로 만들어지기 때문에 + 연산을 할 수 없다. 하지만 자바에서는 래퍼 클래스에 대한 연산이 시도될 때, 오토 언박싱을 해서 둘 다 int형으로 만들어서 연산을 수행한다. 래퍼 클래스와 기본형 간의 연산도 마찬가지로 동작한다.

 

주의해야 할 연산은 '==' 연산이다.

 

Integer i1 = new Integer(10);
Integer i2 = new Integer(10);

if (i1 == i2)
    System.out.println("같다");
else
    System.out.println("다르다");

 

이 코드를 수행하면, "다르다"라는 문자열이 출력된다. '==' 연산은 참조 변수의 주소값을 비교하는 연산이다. i1과 i2는 그 안에 담고 있는 값은 같지만 힙 메모리의 별도 주소공간에 만들어지는 다른 객체다. 따라서 참조 값이 다르기 때문에 i1 == i2 라는 조건은 거짓이 된다. 

 

만약 내용을 검사하려면 '.equals()' 메소드를 사용해야한다.

반응형

댓글