: 언박싱은 박싱한 객체에 대해서만 가능하다
주의할 것은 모든 객체가 값 형식으로 언박싱 될 수는 없습니다
즉 이전에 값 형식을 박싱하여 생성된 객체에 한해서 언 박싱이 가능합니다
다시 말해 아래의 코드처럼 박싱이 일어나지 않은 객체에 대한 언박싱 시도는 실패하게 됩니다
object o = new object();
int j = (int) o; //캐스팅 예외 발생
: 언박싱은 박싱하기 전 형식을 준수해야 한다
또한 박싱 할 때의 값 형식의 타입을 준수해야 합니다
보통 형 변환 시 short 타입을 더 큰 자료형인 int 타입으로 변환하는 것은 아무런 문제가 없습니다
그러나 short 타입을 박싱 한 객체를 int 타입으로 언박싱 하는 것은 허용되지 않습니다
short i = 123; //값 형식
object o = i; //박싱
int j = (int) o; //int로 언박싱 불가능
중간 언어인 IL 코드 열어보면 박싱 언박싱이 일어나는 것을 명확히 알 수 있습니다

* 박싱/언박싱 그리고 성능
값 형식 <-> 참조 형식 즉 스택과 힙 영역을 자유로이(?) 오가는 박싱/언박싱은 무조건 좋은 걸까요?
그렇지 않습니다. 박싱/언박싱은 비용이 꽤나 많이 드는 작업임을 유념해야 합니다
값 형식을 박싱 하는 경우 완전히 새로운 객체를 할당하고 구성해야 하며 언박싱에 필요한 캐스팅도
상당한 계산 과정이 필요합니다
MSDN 에서는 이 과정에 대한 비용을 다음과 같이 설명하고 있습니다
“boxing 및 unboxing 과정에는 많은 처리 작업이 필요합니다. 값 형식을 boxing할 때는 완전히 새로운 개체가
만들어져야 하며, 이러한 작업에는 할당 작업보다 최대 20배의 시간이 걸립니다. unboxing을 할 때는 캐스팅
과정에 할당 작업보다 4배의 시간이 걸릴 수 있습니다”
* 그럼 언제 그리고 왜 사용하는가?
이처럼 비용이 많이 들고 성능에 악영향을 끼치는 박싱/언박싱은 왜 지원하는 걸까요?
이유야 찾아 보면 여러 가지 있겠습니다만, 대표적으로 사용상의 편의성이라 말하고 싶네요
C#의 모든 자료형은 System.Object 로부터 상속을 받게 됩니다
즉 System.Object 로 데이터를 처리할 경우 특정 타입으로 인한 제약사항에서 자유로워 지게 됩니다
이것은 배열과 같은 복합자료를 다룰 경우 유용한데요.
닷넷 프레임워크에서 제공하는 System.Collections.ArrayList 클래스는 대표적인 복합자료형 입니다
ArrayList에 저장할 수 있는 요소의 타입은 어떤 형식이라도 상관이 없는데요. 아래 코드를 보면
ArrayList에 정수, 문자, 객체 등을 그 타입을 가리지 않고 마구(?) 추가할 수 있습니다
System.Collections.ArrayList al = new System.Collections.ArrayList();
al.Add(123); //정수 추가
al.Add("안녕하세요"); //문자열 추가
al.Add(new Program()); //객체 추가
이것은 ArrayListy의 Add 메서드가 object 타입의 매개변수를 취하고 있기 때문입니다
즉 object 타입이면 모두 가능하며 이 말은 곧 C#의 모든 자료형을 저장할 수 있다는 의미입니다
이와 같이 특정 자료형에 구애 받지 않고 복합 자료를 다룰 경우 편리성을 제공하게 되는 것입니다
(배열과 같이 동일한 타입의 자료만 저장할 수 있는 것과는 대조됩니다)
그러나 결국 al.Add(123) 과 같은 명령은 123이라는 정수형 자료가 object 타입으로 박싱이 일어나게 되며
데이터를 가져올 때에 해당 타입으로 언박싱을 해줘야 합니다
object o = al[0];
int j = (int) o;
즉 편리하기는 하지만 그 만큼의 비용은 지불해야 하는 것입니다
또한 위와 같이 ArrayList에 여러 타입의 자료를 저장하게 되면 값을 가져올 때 박싱 되기 전 자료형으로
명확히 캐스팅을 해줘야 하기 때문에 형식에 대한 불안정성도 증가하게 됩니다
(참고로 닷넷 2.0 부터는 이러한 ArrayList 의 단점인 고비용과 형식 불안정성을 개선하기 위해
지네릭 버전의 컬렉션을 제공하게 됩니다)
* 자바의 Wrapper 클래스
자바에서는 기본 자료형을 객체처럼 생성하기 위해서 Wrapper 클래스를 사용하게 됩니다
아래코드는 기본 자료형 int형 정수를 Wrapper클래스인 Integer 클래스를 이용하여 객체로 생성하고 있습니다
Integer i = new Integer(123);
자바에서는 이와 같이 기본 자료형에 대한 Wrapper 클래스를 제공하는데요
이처럼 기본 데이터 자료형을 Wrapper 객체로 생성하는 것을 박싱이라 하며
Wrapper 객체에서 기본 자료형의 값을 가져오는 것을 언박싱이라 합니다
다만 닷넷에서는 박싱 시, 자바에서와 같이 기본자료형에 대응하는 Wrapper 클래스가 제공되는 것은 아니지만
그 동작 방식은 매우 유사하며 내부적으로 값 형식을 박싱하면 System.Object 객체로 랩핑 되거나 값 형식이 구현한
인터페이스 형식으로 묵시적 변환이 일어납니다
따라서 자바의 Auto Boxing과 Auto UnBoxing 에 따른 편의성 제공되지는 않습니다
다만 개념적 그리고 메모리 구조적인 측면에서는 두 언어에서의 박싱/언박싱은 거의 동일한 개념입니다
감사합니다. 즐거운 한 주 되세요~~