원시타입, 참조타입(Primitive Type, Reference Type)
자바에서는 데이터 타입에 크게 두 가지 원시 타입(Primitive Type)
과 참조타입(Reference Type)
이 있다.
원시 타입
은 쉽게 말해, 정수, 실수, 문자, 논리 리터럴등의 실제 데이터 값을 저장하는 타입이고,
참조 타입
은 객체(Object)의 번지를 참조(주소를 저장)하는 타입으로** 메모리 번지 값을 통해 객체를 참조하는 타입**이다.
원시 타입(Primitive Type)
종류 | 데이터형 | 크기(byte / bit) | 표현 범위 |
---|---|---|---|
논리형 | boolean | 1 / 8 | true 또는 false |
문자형 | char | 2 / 16 | ‘\u0000’ ~ ‘uFFFF’ (16비트 유니코드 문자 데이터) |
정수형 | byte | 1 / 8 | -128 ~ 127 |
정수형 | short | 2 / 16 | -32768 ~ 32767 |
정수형 | int | 4 / 32 | -2147483648 ~ 2147483647( -21억 ~ + 21억) |
정수형 | long | 8 / 64 | -9223372036854775808 ~ 9223372036854775807(-100경 ~ + 100경) |
실수형 | float | 4 / 32 | 1.4E-45 ~ 3.4028235E38 |
실수형 | double | 8 / 64 | 4.9E-324 ~ 1.7976931348623157E308 |
-
boolean
- 저장 가능한 범위 true/ false
- Java가 데이터를 다루는 최소 범위가 1 Byte 이기 때문에 낭비적이지만 1 Byte를 사용한다.
-
char
- Java의 경우 Unicode를 사용, 동양의 글자의 경우 2 Byte 필요하기때문에 char 의경우 2 Byte 이용한다
- Java에서 유일하게 제공되는 unsigned 형태다.
_unsigned : 음수 없이 0부터 시작하여 양수 값만 가지는 데이터 형태 _
2 Byte = 16진수 0x00 = 0000 0000 0000 0000 맨 앞 1 Bit를 가지고 음수나 양수 를 나타낸다.
하지만 char형은 unsigned 형식이기 때문에 맨 앞 비트를 음수 양수 형식 으로 사용하지 않는다.
char 형이 1111 1111 1111 1111 의 Bit를 가지고 있을때 10진수의 값 65535 short 형이 1111 1111 1111 1111 의 Bit를 가지고 있을때 10진수의 값 -1
char a = ‘A’; b = ‘B’; 일때 if (a > b) 가 가능한이유는,
char형은 유니코드 정수형태로 저장 char a = ‘A’ 일시 a변수에는 ‘A’ 의 정수 값인 65가 들어간다.
JVM의 피연산자 스택이 피연산자를 4 Byte 단위로 저장 하기 때문에 int보다 작은 자료형의 값을 계산시** int 형으로 형변환 되서 연산이 수행**된다.
정수형 데이터를 사용하게 되면 JVM에서 기본적으로 int형 데이터타입의 데이터로 인식을 해주게 된다.
int형 데이터 타입의 범위를 넘어서는 long 데이터 타입의 정수를 사용하고자 하는 경우에는 정수 데이터 맨 뒤 쪽에, 접미사 ‘l’ 이나 ‘L’을 붙여줘야한다.
소문자 l 은 숫자 1과 혼돈할 우려가 있기 때문에 대문자 L을 붙여 사용하는것이 좋다.
- byte
- short
- int
- long
위는 정수형 데이터들의 표현할 수 있는 범위를 나타낸 것이다.
숫자형 데이터 타입에서는 맨 앞의 비트를 부호를 나타내는 비트로 사용하기에 바이트 크기에서 1작은 승수로 범위를 표현된다.
범위에서 -1를 한 이유는 중간에 0이 있기 때문이다.
실수형 데이터타입에서는 double형 데이터타입이 기본 데이터타입이다.
기본형 데이터타입이 double형 이기 때문에 float형 데이터타입의 실수형 데이터를 사용하고자 하는 경우에도long형과 마찬가지로 실수 데이터 맨 뒤 쪽에 접미사 ‘f’나 ‘F’를 붙여줘야한다.
float형 데이터타입보다 double형 데이터타입이 두배정도 더 정밀한 데이터를 표현할 수 있다.
-
float
-
float fl = 3.14F; or float fl = 3.14f;
-
f를 붙여 주지 않으면 double형 데이터로 인식하기에 꼭 붙여 줘야한다.
-
-
double
-
temp = 1e-3;
-
e 뒤에 붙은 숫자가 10의 몇승을 나타낸다. 지금 1e-3의 경우 10의 -3승 으로서 0.001 과 같다 1e3 == 1000 (10의 3승 )과 같다.
-
참조 타입(Reference Type)
참조 타입
은 원시 타입을 제외한 타입들(문자열, 배열, 열거, 클래스, 인터페이스)을 말한다.
Java에서 실제 객체
는 힙 영역
에 저장되며 참조 타입 변수
는 스택 영역
에 실제 객체들의 주소를 저장하여, 객체를 사용할때 마다 참조 변수에 저장된 객체의 주소를 불러와 사용하는 방식이다.
- EXAMPLE
스택 영역 | 힙 영역 |
---|---|
int age = 25 char cc = ‘c’ String name = 10101번지 |
10101번지 : “커피” |
- 정적 메모리 스택(Stack) 영역
스택 영역에는 기본타입 변수가 할당되고 변수의 실제 값들이 저장된다.
참조 타입의 변수들은 이 스택 영역에서 힙 영역에 생성된 객체들의 주소 값을 저장하고 있는다.
객체 안의 메소드의 작업이 종료되면 할당되었던 메모리 공간은 반환되어 비워진다.
- 동적 메모리 힙(Heap) 영역
힙 영역에는 객체와 배열이 생성된다.
그리고 참조타입
(배열, 클래스, 인터페이스 등)들이 이 객체들의 주소
를 스택 영역
에 저장한다.
기본타입 변수들과는 다르게 크기가 정해져 있지 않다.
프로그램 실행시 메모리에 동적으로 할당된다.
참조하는 변수가 없으면 자바의 가비지 컬렉터
가 제거한다.
가비지 컬렉터(Garbage collector)
: 메모리의 힙 영역에 할당된 더 이상 사용되지 않는 객체를 제거 하는 역할
이렇게 객체를 제거하며 메모리가 관리된다.
Boxing, Unboxing
Boxing(박싱)
은 원시 타입을 참조 타입으로 변환 시키는 것을 말하고, Unboxing(언박싱)
은 참조 타입을 원시 타입으로 변환 시키는 것을 말한다.
자바 1.5 이전에는 일일히 변환 과정을 거쳐주어야 했지만, 자바 1.5부터 추가된 Auto Boxing / Unboxing
기능으로 아래의 예시와 같이 명시적으로 원시타입을 참조타입으로 감싸주지 않아도 자동으로 Boxing / Unboxing 해준다.
int i = 10;
Integer integer = i;
이러한 Auto Boxing / Unboxing
기능은 메모리 누수의 원인이 될 수도 있다.
원시 타입과 참조 타입 차이
기능적으로 원시 타입과 참조 타입은 크게 2가지 차이가 있다.
1. Null 포함 가능 여부
원시타입은 null을 담을 수 없지만, 참조 타입은 가능하다.
// 불가능
int i = null;
// 가능
Integer integer = null;
2. 제너릭 타입에서 사용 가능 여부
원시타입은 제너릭 타입에서 사용할 수 없지만, 참조 타입은 가능하다.
// 불가능
List<i> list;
// 가능
List<Integer> list;
원시 타입의 장점
원시 타입은 성능 상의 이점이 있다.
1. 접근속도
**원시타입은 '스택' 메모리
에 값이 존재한다. **
반면에** 참조타입은 하나의 인스턴스이기 때문에 '스택' 메모리
에는 참조값만** 있고, 실제 값은 힙 메모리
에 존재한다.
그리고 값을 필요로 할 때마다 언박싱 과정을 거쳐야 하니 원시타입과 비교해서 접근 속도가 느려지게 된다. 예외적으로 엄청 큰 숫자를 복사해야 한다면, 참조값만 넘길 수 있는 참조타입이 좋을 수 도 있다.
2. 메모리 양
원시타입이 사용하는 메모리 | 참조타입이 사용하는 메모리 |
---|---|
boolean - 1bit | Boolean – 128 bits |
byte - 8bits | Byte - 128bits |
short, cagr - 16bits | Short, Charater - 128bits |
int, float - 32bits | Integer, Float - 128bits |
long, double - 64bits | Long, Double - 196bits |
원시 타입보다 참조 타입이 사용하는 메모리양이 압도적으로 높다.
따라서 메모리 사용적으로도 원시 타입이 참조 타입보다 효율적으로 사용할 수 있다.
🙆♂️ 참고사이트 🙇♂️
Java에서 원시타입 vs 참조타입 어떤 걸 사용해야 할까?
자바의 변수 / 기본 타입과 참조 타입 / 메모리의 힙영역과 스택영역[우종선]
댓글남기기