minlog

박싱과 언박싱

2023.11.11·조회수:
0
thumbnail
 

박싱과 언박싱

Boxing : 값타입을 참조타입으로 변환하는 기법 UnBoxing : 참조타입을 값타입으로 변환하는 기법

1. 값타입

스택 : 저장

  • 선언되는 즉시 메모리를 할당하게 된다.
  • 따라서 생성과 동시에 값을 할당할 수도 있다. int a = 3;

2. 참조타입

힙 : 저장 스택 : (C의 포인터처럼) 저장된 것의 주소값만 가짐

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


// 유리병(값타입) -> 유리병 그대로 배달 X -> 택배차 : 거부 (우린 택배박스만 받는다)
// 유리병 -> 택배포장 -> 택배차
// 값타입 -> 참조타입으로 포장(박싱) -> 참조타입만 받는 매개변수에 전달
public class BoxingTest
{
    public static void Main(string[] args)
    {
        int p = 123;       // 값타입
        Object o = p;      // (자동으로 박싱) 박싱후 o에 들어가는 상황
        int j = (int)o;    // 언박싱 : 내가 명시적으로 캐스팅을 해줘야 한다

        Console.WriteLine(p);
        Console.WriteLine(o);
        Console.WriteLine(j);
    }
}

비유하자면 우리집이라는 객체를 메모리에할당할 경우,
우리집은 힙 영역에 저장되고 스택 영역에서는 우리집을 가르키는 주소
* 참조타입은 새로운 값을 할당하기 위해서는 new를 통해 선은을 해줘야 한다.

class 우리집
{
    public void 안방()
    {

    }
}


public class BoxingTest
{
    public static void Main(string[] args)
    {
        int a = 10; // 값타입
        우리집 b201호 = new 우리집(); // 참조타입
        b201호.안방();
    }
}

쿠팡이라는 온라인마켓 int 모양의 상품, double 모양의 상품, String 모양의 상품, 객체 모양의 상품 (별의별 물건 다 팜) 할때마다 int 전용 택배차 따로, double 전용 택배차를 일일히 다 만들면 비효율적이다 포장 -> 모두 같은 택배차에 실어 나르자

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


public class 쿠팡맨
{
    public void 배송출발(Object o)
    {
        Console.WriteLine("배달하는 물건 : "+ o );
    }
}

public class BoxingTest
{
    public static void Main(string[] args)
    {
        쿠팡맨 man = new 쿠팡맨();
        int 주문상품1 = 123;          // 값타입 (그냥 택배차에 못 실음)
        double 주문상품2 = 3.14;      // 값타입
        String 주문상품3 = "이미포장됨";  // 참조타입

        man.배송출발(주문상품1);      // 값 타입이 자동으로 참조타입으로 박싱된 후 전달됨 (택배포장이 된 후)
        man.배송출발(주문상품2);      // 값 타입이 자동으로 참조타입으로 박싱된 후 전달됨 (택배포장이 된 후)
        man.배송출발(주문상품3);
        man.배송출발(man); // 쿠팡맨은 포장 안하고 그냥 택배차에 올라탐 (참조타입은 그냥 들어감)
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections; // ArrayList 쓰려고 추가함

public class BoxingTest
{
    public static void Main(string[] args)
    {
        ArrayList list = new ArrayList();

        // 1. 박싱되는 예시
        list.Add(new BoxingTest()); // list[0] 공간 : 참조타입인 객체가 전달
        list.Add("안녕하세요");     // list[1] 공간 : 참조타입인 문자열이 전달 (heap 영역에 저장 근데 문자열은 특이하게도 new 키워드를 안써도 된다)
        list.Add(3.14);             // list[2] 공간 : 값타입인 실수가 (자동으로 박싱이 된 후) 전달
        list.Add(123);              // list[3] 공간 : 값타입인 정수가 (자동으로 박싱이 된 후) 전달

        // 2. 정상 삽입됐나 확인
        Object o1 = list[2];        // list.Add(3.14); 이게 정상적으로 삽입됐나?
        Object o2 = list[3];        // list.Add(123); 이게 정상적으로 삽입됐나?

        Console.WriteLine(o1);
        Console.WriteLine(o2);

        // 3. 전체 출력
        PrintValues(list);
    }

    // 출력 함수
    public static void PrintValues(IEnumerable 리스트)
    {
        foreach (Object obj in 리스트)
        {
            Console.WriteLine("{0}", obj);
        }
    }
}