본문 바로가기

언어/자바

Autoboxing And Unboxing

reference: https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

What it Autoboxing and unboxing?

Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.

 

자바에서는 기본 자료형 (int, double) 등을 이에 상응하는 객체 (Integer, Double)가 있다. 후자를 Wrapper class라고 부른다.

이 때 기본자료형을 wrapper class로 변환하는 것을 boxing, 그 반대를 unboxing이라고 한다.

이 것을 직접 할 수도 있지만 번거로울 수 있다. 

자바 컴파일러는 이걸 자동으로 해주는데 이것을 autoboxing, auto-unboxing이라고 한다.

 

이를 통해 boxing, unboxing 때문에 코드가 장황해질 필요가 없다.

아래표는 자바 컴파일러가 autoboxing, autounboxing을 제공하는 기본 자료형과 wrapper class를 표시한 것이다.

기본형 Wrapper class
boolean Boolean
byte Byte
char Character
float Float
int Integer
long Long
short Short
double Double

 

How?

Wrapper class는 valueOf 정적 메소드와 ~~Value와 같은 메소드를 제공한다.

예를 들어 Integer 클래스의 메소드를 보자.

public int intValue() {
	return value;
}


public static Integer valueOf(String s, int radix) throws NumberFormatException {
	return Integer.valueOf(parseInt(s,radix));
}

 

이 메소드 호출을 통해 boxing, unboxing이 이뤄진다.

이 메소드 호출을 우리가 직접하지 않고 자바 컴파일러가 적용해주는 시점이 있는데 이 때 autoboxing, autounboxing이 이뤄진다.

 

autoboxing이 적용되는 시점:

Converting a primitive value (an int, for example) into an object of the corresponding wrapper class (Integer) is called autoboxing. The Java compiler applies autoboxing when a primitive value is:

  • Passed as a parameter to a method that expects an object of the corresponding wrapper class.
  • Assigned to a variable of the corresponding wrapper class.

autounboxing이 적용되는 시점:

Converting an object of a wrapper type (Integer) to its corresponding primitive (int) value is called unboxing. The Java compiler applies unboxing when an object of a wrapper class is:

  • Passed as a parameter to a method that expects a value of the corresponding primitive type.
  • Assigned to a variable of the corresponding primitive type.

Example 1

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(i);

li는 Integer를 원소로 받는 리스트이다. 하지만 add호출에서 들어가는 값은 primitive type인 int이다. 

이것이 가능한 이유는 int -> Integer로 Autoboxing이 이뤄지고 있기 때문이다.

위 코드는 실제로는 아래와 같이 실행된다.

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(Integer.valueOf(i));

 

Example 2

public static int sumEven(List<Integer> li) {
    int sum = 0;
    for (Integer i: li)
        if (i % 2 == 0)
            sum += i;
        return sum;
}

int에 Integer 객체의 값을 누적하고 있다. 이 때 %연산과 +=연산은 Integer에서는 불가하므로 int로 변환이 필요하다.

따라서 실제로 위 코드는 아래와 같이 실행될 것이다.

public static int sumEven(List<Integer> li) {
    int sum = 0;
    for (Integer i : li)
        if (i.intValue() % 2 == 0)
            sum += i.intValue();
        return sum;
}