Lesson: Numbers and Strings [Autoboxing and Unboxing]

2024. 6. 5. 17:40High Level Programming Language/Learning the Java Language

Autoboxing and Unboxing

오토박싱은 Java 컴파일러가 기본 유형과 해당 객체 래퍼 클래스 간에 수행하는 자동 변환입니다. 예를 들어 int를 Integer로, double을 Double로 변환하는 등의 작업을 수행합니다. 변환이 반대 방향으로 진행되는 경우 이를 언박싱(Unboxing)이라고 합니다.

여기 가장 심플한 오토박싱 샘플 코드가 있습니다.

Character ch = 'a';

 

이 섹션의 나머지 예제에서는 제네릭을 사용합니다. 아직 제네릭 신택스에 익숙하지 않다면 제네릭(업데이트됨) 단원을 참조하세요.

다음 코드를 고려해보세요.

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

 

Integer 객체가 아닌 int 값을 li의 엘리먼트로 추가하더라도 코드가 컴파일됩니다. li는 int 값 리스트가 아니라 Integer 객체 리스트이기 때문에 Java 컴파일러가 컴파일 시간 오류를 발행하지 않는 이유가 궁금할 수 있습니다. 컴파일러는 i에서 Integer 객체를 생성하고 해당 객체를 li에 추가하므로 오류를 생성하지 않습니다. 따라서 컴파일러는 런타임 시 이전 코드를 다음으로 변환합니다.

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

 

기본 값(예: int)을 해당 래퍼 클래스(Integer)의 객체로 변환하는 것을 오토박싱이라고 합니다. Java 컴파일러는 기본 값이 다음과 같은 경우 오토박싱을 적용합니다.

  • 해당 래퍼 클래스의 객체를 기대하는 메서드에 파라미로 전달됩니다.
  • 해당 래퍼 클래스의 변수에 할당됩니다.

다음 메서드를 고려해 보세요

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

 

나머지(%) 및 단항 더하기(+=) 연산자가 Integer 객체에 적용되지 않기 때문에, Java 컴파일러가 오류를 발생시키지 않고 메서드를 컴파일하는 이유에 대해 궁금할 수 있습니다. 컴파일러가 오류를 발생시키지 않는 이유는 런타임에 Integer를 int로 변환하기 위해 intValue 메서드를 호출하기 때문입니다.

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

 

래퍼 유형(Integer)의 객체를 해당 기본(int) 값으로 변환하는 것을 unboxing이라고 합니다. Java 컴파일러는 래퍼 클래스의 객체가 다음과 같은 경우 언박싱을 적용합니다.

  • 해당 기본 유형의 값을 기대하는 메소드에 매개변수로 전달됩니다.
  • 해당 기본(primitive) 타입의 변수에 할당됩니다.

Unboxing 예제는 이것이 어떻게 작동하는지 보여줍니다:

import java.util.ArrayList;
import java.util.List;

public class Unboxing {

    public static void main(String[] args) {
        Integer i = new Integer(-8);

        // 1. Unboxing through method invocation
        int absVal = absoluteValue(i);
        System.out.println("absolute value of " + i + " = " + absVal);

        List<Double> ld = new ArrayList<>();
        ld.add(3.1416);    // Π is autoboxed through method invocation.

        // 2. Unboxing through assignment
        double pi = ld.get(0);
        System.out.println("pi = " + pi);
    }

    public static int absoluteValue(int i) {
        return (i < 0) ? -i : i;
    }
}

 

이 프로그램은 다음과 같은 출력을 만듭니다.

absolute value of -8 = 8
pi = 3.1416

 

 

오토박싱과 언박싱을 통해 개발자는 더욱 깔끔한 코드를 작성하여 읽기 쉽게 만들 수 있습니다. 다음 표에는 Java 컴파일러에서 자동박싱 및 언박싱을 위해 사용하는 기본 유형과 해당 래퍼 클래스가 나열되어 있습니다.

 

Primitive type Wrapper class
boolean Boolean
byte Byte
char Character
float Float
int Integer
long Long
short Short
double Double