오토박싱 및 언박싱

오토박싱 은 Java 컴파일러가 기본 타입과 해당 객체 래퍼 클래스 간에 수행하는 자동 변환입니다. 예를 들어, intInteger로, doubleDouble로 변환하는 등의 작업을 수행합니다. 변환이 다른 방향으로 진행되면 이를 언박싱이라고 합니다.

다음은 가장 간단한 오토박싱의 예입니다:

Character ch = 'a';

이 섹션의 나머지 예제에서는 제네릭을 사용합니다. 아직 제네릭 구문에 익숙하지 않다면 제네릭 섹션을 참조하세요.

다음 코드를 살펴보세요:

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

intInteger 객체가 아닌 기본 타입으로 int 값을 추가해도 코드가 컴파일됩니다. intint 값의 목록이 아니라 Integer 객체의 목록이기 때문에 Java 컴파일러가 컴파일 타임 오류를 발생시키지 않는 이유가 궁금할 수 있습니다. 컴파일러는 i에서 Integer 객체를 생성하고 이 객체를 int에 추가하기 때문에 에러를 생성하지 않습니다. 따라서 컴파일러는 런타임에 이전 코드를 다음과 같이 변환합니다:

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

원시값(예: int)을 해당 래퍼 클래스 Integer의 객체로 변환하는 것을 오토박싱이라고 합니다. Java 컴파일러는 프리미티브 값일 때 오토박싱을 적용합니다:

  • 해당 래퍼 클래스의 객체를 기대하는 메서드에 매개변수로 전달된 경우.
  • 해당 래퍼 클래스의 변수에 할당된 경우.

다음 메서드를 생각해 보세요:

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

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

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

래퍼 타입의 객체 Integer를 해당 프리미티브(int) 값으로 변환하는 것을 언박싱이라고 합니다. Java 컴파일러는 래퍼 클래스의 객체일 때 언박싱을 적용합니다:

  • 해당 프리미티브 타입의 값을 기대하는 메서드에 매개변수로 전달됩니다.
  • 해당 기본 타입의 변수에 할당됩니다.

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

import java.util.ArrayList;
import java.util.List;
 
public class Unboxing {
 
    public static void main(String[] args) {
        Integer i = Integer.valueOf(-8);
 
        // 1. Unboxing through method invocation
        int absVal = absoluteValue(i);
        System.out.println("absolute value of " + i + " = " + absVal);
 
        List<Double> doubles = new ArrayList<>();
        doubles.add(3.1416);    // Π is autoboxed through method invocation.
 
        // 2. Unboxing through assignment
        double pi = doubles.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 typeWrapper class
booleanBoolean
byteByte
charCharacter
floatFloat
intInteger
longLong
shortShort
doubleDouble