원시 타입(Primitive Type), 참조 타입(Reference Type)

YH·2023년 3월 25일
0

✅ 원시 타입(Primitive Type)

: 정수, 실수, 문자, 논리 리터럴 등의 실제 데이터 값을 저장하는 타입

  • boolean, char, byte, short, int, long, float, double 8가지

  • 스택(Stack) 메모리에 저장 됨

  • boolean

    • true 또는 false를 저장
    • Java의 최소 데이터 단위인 1Byte를 사용
  • char

    • 기본적으로 1Byte를 사용하나, 한글이나 일본어등 동양권 언어에는 Unicode를 사용하므로 2 Byte를 사용
    • Java에서 유일한 Unsigned(음수 값이 존재하지 않음) 데이터 형태
  • byte, short, int, long

    • 정수형 데이터 타입
    • byte, short, int의 경우 4 Byte단위로 저장되며, long은 8 Byte
    • Java에서 long 사용 시 접미사 L을 붙여 long 타입임을 명시해줌
  • float, double

    • 실수형 데이터 타입
    • 실수형의 기본 데이터 타입은 double로 float을 사용할 경우 접미사 F를 명시
    • float는 4 Byte, double은 8 Byte 사이즈 단위로 저장

✅ 참조 타입(Reference Type)

  • 객체의 주소를 참조하는 타입으로, 메모리 번지 값을 통해 객체를 참조하는 타입
  • Java에서 Primitive Type을 제외한 타입들이 모두 Reference 타입이며, java.lang.Object 클래스를 상속하는 모든 클래스들을 말함
  • 클래스(Class), 인터페이스(Interface), 배열(Array), 열거(Enum) 타입이 있음
  • 실제 객체는 Heap 영역에 저장되며, 참조 타입 변수는 Stack 영역에 실제 객체의 주소를 저장하여 사용 시 객체의 주소를 불러와 사용한다.
  • Null 값 존재 가능

✅ 원시 타입과 참조 타입의 차이점

  1. Null 포함 여부

    • 원시 타입은 Null 포함 불가, 참조 타입은 가능
  2. 제네릭 타입에서 사용 가능 여부

    • 원시 타입은 제네릭 타입에서 사용 불가, 참조 타입은 가능
  3. 원시 타입이 성능 상 참조 타입보다 좋다

    • 원시 타입은 스택 메모리, 참조 타입은 스택에 참조 값이 있고 실제 객체는 힙에 있으므로 사용 시 원시 타입이 상대적으로 빠르고, 참조 타입은 사용 시 Unboxing을 거치므로 느려짐
    • 기본적으로 사용하는 메모리 양이 원시 타입이 훨씬 적다.

Stack 영역, Heap 영역

  • Stack 영역
    • Primitive 타입 변수들이 할당되고 변수의 실제 값들이 저장 됨
    • Primitive 타입들은 크기가 정해져 있음
    • 메모리에 정적으로 할당되고 컴파일 됨
    • 객체를 사용 후 할당되었던 메모리 공간은 반환되어 버려짐
  • Heap 영역
    • 객체와 배열이 생성되며, 참조 타입들의 주소가 저장 됨
    • 크기가 정해져 있지 않음
    • 프로그램 실행 시 메모리에 동적으로 할당 됨
    • 참조하는 변수가 없으면 Garbage Collector가 제거 함

Boxing, Unboxing

  • Boxing: 원시 타입을 참조 타입으로 변환 하는 것
  • Unboxing: 참조 타입을 원시 타입으로 변환 하는 것

✅ 원시 타입 및 참조 타입을 파라미터로 전달한다면?

❓원시 타입 및 참조 타입을 파라미터로 전달하면, Call by Value, Call by Reference, Call by Address 중 어떤 것이 맞을까?

✔️ Call by Value : 메소드를 호출할 때, 메소드의 매개 변수(파라미터)가 지정한 변수 값의 복사본을 전달함. 값 자체를 복사해서 전달했기 때문에 수정자의 파라미터 값을 변경해도 호출자의 기존 값은 전혀 영향을 받지 않음

✔️ Call by Reference : 메소드를 호출할 때, 매개 변수로 지정한 값에 대한 참조 주소값 자체를 전달함. 값 자체가 아닌 값을 참조하고 있는 메모리 주소를 전달했기 때문에 수정자에서 값을 수정하면 호출자의 값에 영향을 줌

✔️ Call by Address : 메소드를 호출할 때, 매개 변수로 지정한 값에 대한 참조 주소 값을 복사하여 전달함. Call by Reference와 마찬가지로 주소 값에 대한 정보를 가지고 있기 때문에 수정자에서 수정 시, 호출자의 값에 영향을 줌

✏️ JAVA는 Call by Reference라는 개념이 적용되지 않는다. C나 C++처럼 포인터를 사용해 직접 참조 주소에 접근할 수 있는 반면, JAVA는 참조 주소에 직접 접근할 수 없기 때문.

✏️ 대신, 참조 타입을 사용하면 참조 주소 값을 복사하여 전달하므로, 사용자 입장에서 볼 때는 Call by Reference와 동일한 동작을 수행하는 것으로 보임.

✏️ 결국, JAVA에서는 Call by ValueCall by Address를 사용한다고 볼 수 있고, 원시 타입을 매개 변수로 전달할 때는 Call by Value, 원시 타입을 제외한 나머지 참조 타입을 전달할 때는 Call by Address로 동작한다.




참고 Reference

profile
하루하루 꾸준히 포기하지 말고

0개의 댓글