[Java] 원시타입과 참조타입이란?

0-x-14·2024년 9월 14일
0

자바를 공부하던 중, boolean은 null값을 허용하지 않는 것과 달리 Boolean은 null값이 허용된다는 사실을 알게 되었다.
boolean과 Boolean의 차이에 대해 찾아보니, boolean은 원시타입인 것과 달리 Boolean은 참조타입이라고 한다...!

이 글에서는 원시타입과 참조타입에 대해 조금 더 정리해보려고 한다.


원시타입과 참조타입이란?

  • 원시타입 : 논리형, 문자형, 정수형, 실수형 등의 실제 데이터(값)을 저장하는 타입
    • int, float, double, boolean 등
  • 참조타입 : 객체가 생성된 메모리의 주소를 저장하는 타입
    • Integer, Float, Double, Boolean 등


실제로 값이 저장되는 영역은?

  • 원시타입의 객체는 JVM 메모리 구조 중 Stack 메모리 영역에 저장된다.
  • 참조타입의 실제 객체는 Heap 영역에 저장되며, 참조타입의 변수는 Stack 영역에 실제 객체 주소의 값을 저장하게 된다.
  • 아래와 같은 두 변수가 있다고 가정해보자.
int age = 25;
String name = "커피";


이 경우, age와 name의 값은 각각 다음과 같은 영역에 저장된다.

스택 영역힙 영역
int age = 25
String name = 1111번지1111번지 : "커피"




Boxing과 Unboxing이란?

  • 참조타입은 원시타입을 박스화한 자료형(boxed primitive type)이라고 할 수 있다.
  • 그래서 원시타입을 참조타입으로 변환하는 과정박싱(Boxing)이라고 한다.
  • 참조타입을 원시타입으로 변환하는 과정언박싱(Unboxing)이라고 한다.

자바 1.5부터 추가된 Auto Boxing / Unboxing 기능으로 인해 명시적으로 형변환을 하지 않아도 자바가 자동으로 박싱과 언박싱을 해준다.
예를 들어 다음 코드처럼 사용 가능하다.
public class BoxingUnBoxing {

	public static void main(String[] args) {

		// Boxing
		int i = 10;
		Integer integer = i; // 원시타입 i를 참조타입 integer에 대입

		System.out.println(i);
		System.out.println(integer);

		// UnBoxing
		Integer integer2 = 20;
		int i2 = integer2; // 참조타입 integer2를 원시타입 i2에 대입

		System.out.println(i2);
		System.out.println(integer2);
	}

}

결과
10
10
20
20




원시타입 vs 참조타입 비교

null을 담을 수 있는가?

  • 원시타입 - 불가능
  • 참조타입 - 가능
int i = null; // 원시타입이므로 불가능
Integer integer = null; // 가능




제네릭 타입에서 사용할 수 있는가?

  • 원시타입 - 불가능
  • 참조타입 - 가능
List<int> i2; // 원시타입이므로 불가능
List<Integer> integer2; // 가능




접근속도?

  • 원시타입(빠름) < 참조타입(느림)
  • 참조타입은 값에 접근할 때 Unboxing 과정을 거쳐야 하므로 원시타입에 비해 접근 속도가 느리다.
  • 단, 예외적으로 엄청 큰 숫자를 복사해야 한다면 참조 타입이 좋을 수도 있다.
    아래 그래프에서 확인할 수 있듯, 원시타입인 long과 참조타입인 Long의 평균 실행시간은 다른 타입들에 비해 차이가 적다.




차지하는 메모리의 양?

  • 참조타입(큼) > 원시타입(작음)
  • 참조타입은 객체로 감싸져있기 때문에 차지하는 메모리의 양이 원시타입에 비해 크다.
원시타입이 사용하는 메모리참조타입이 사용하는 메모리
boolean - 1bitBoolean - 128bits
byte - 8bitsByte - 128bits
short, char - 16bitsShort, Character - 128bits
int, float - 32bitsInteger, Float - 128bits
long, double - 64bitsLong, Double - 196bits




결론!

원시타입은 성능과 메모리 면에서 장점이 있으므로 원시타입 사용을 먼저 고려해보면 좋을 것 같다.
다만 null이나 제네릭 타입을 사용할 경우에는 참조타입을 사용해야 한다.






참고 링크




0개의 댓글

관련 채용 정보