JAVA Generic(제네릭)에대해 알아보던 중 Generic에 넣을 수 있는 타입과 그렇지 못한 타입이 있다는것을 알게되어 정리를 해보려고 한다.
Generic에대해 궁금하다면 아래의 링크 클릭
Primative Type는 말 그대로 자바에서 기본으로 제공해 주고있는 타입이다.
기본형 타입(Primitive type)
- 총 8가지의 기본형 타입(Primitive type)을 미리 정의하여 제공한다.
- 기본값이 있기 때문에 Null이 존재하지 않는다. 만약 기본형 타입에 Null을 넣고 싶다면 래퍼 클래스를 활용한다.
- 실제 값을 저장하는 공간으로 스택(Stack)메모리에 저장된다.
- 만약 컴파일 시점에 담을 수 있는 크기를 벗어나면 에러를 발생시키는 컴파일 에러가 발생한다. 주로 문법상의 에러가 많다. 예를 들어 ;을 안붙였다는 이유로 빨간 줄이 쳐지는 경우
타입 | 할당되는 메모리 크기 | 기본값 | 데이터의 표현 범위 | ||
논리형 | boolean | 1 byte | false | true, false | |
정수형 | byte | 1 byte | 0 | -128 ~ 127 | |
short | 2 byte | 0 | -32,768 ~ 32,767 | ||
int(기본) | 4 byte | 0 | -2,147,483,648 ~ 2,147,483,647 | ||
long | 8 byte | 0L | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | ||
실수형 | float | 4 byte | 0.0F | (3.4 X 10-38) ~ (3.4 X 1038) 의 근사값 | |
double(기본) | 8 byte | 0.0 | (1.7 X 10-308) ~ (1.7 X 10308) 의 근사값 | ||
문자형 | char | 2 byte (유니코드) | '\u0000' | 0 ~ 65,535 |
참조형 타입(Reference type)
- 기본형 타입을 제외한 타입들이 모두 참조형 타입(Reference type)이다.
- 빈 객체를 의미하는 Null이 존재한다.
- 값이 저장되어 있는 곳의 주소값을 저장하는 공간으로 힙(Heap) 메모리에 저장된다.
- 문법상으로는 에러가 없지만 실행시켰을 때 에러가 나는 런타임 에러가 발생한다. 예를 들어 객체나 배열을 Null 값으로 받으면 NullPointException이 발생하므로 변수값을 넣어야 한다.
타입 | 기본값 | 할당되는 메모리 크기 | |
배열(Array) | Null | 4 byte (객체의 주소값) | |
열거(Enumeration) | Null | ||
클래스(Class) | Null | ||
인터페이스(Interface) | Null |
결론
두개의 타입을 핸들링함에 있어 가장 크게 신경써야 하는것은 NULL의 존재유무와 값의 저장 위치이다.
NULL의 존재유무
데이터를 확인함에 있어 Primitive type과 NULL과의 비교를 사용하게 되면 에러가 발생하기 때문에 꼭 신경써야한다.
저장 위치
- Primitive type은 stack에 값이 저장된다.
- Reference type은 stack에 heap의 위치를 저장하고 heap에 값을 저장한다.
이 두개를 잘 기억하고 아래의 예제를 보겠다.
Code
/* Primitive type 선언 및 초기화 후 출력 (stack 값) */
int primitiveType_01 = 1;
int primitiveType_02 = 2;
int primitiveType_03 = 3;
System.out.println("primitiveType_01 : "+ primitiveType_01 + ", primitiveType_02 : "+ primitiveType_02 + ", primitiveType_03 : " + primitiveType_03);
/* Primitive type 값 변경 후 출력 (stack 값) */
primitiveType_01 = primitiveType_02;
primitiveType_02 = 4;
primitiveType_03 = 5;
System.out.println("primitiveType_01 : "+ primitiveType_01 + ", primitiveType_02 : "+ primitiveType_02 + ", primitiveType_03 : " + primitiveType_03);
System.out.println("\n\n\n");
/* Reference type 선언 및 초기화 후 출력(stack 값, heap 값) */
int[] ReferenceType_01 = {1};
int[] ReferenceType_02 = {2};
int[] ReferenceType_03 = {3};
System.out.println("ReferenceType_01 : "+ ReferenceType_01 + ", ReferenceType_02 : "+ ReferenceType_02 + ", ReferenceType_03 : " + ReferenceType_03);
System.out.println("ReferenceType_01 : "+ ReferenceType_01[0] + ", ReferenceType_02 : "+ ReferenceType_02[0] + ", ReferenceType_03 : " + ReferenceType_03[0]);
/* Reference type 값 변경 후 출력(stack 값, heap 값) */
ReferenceType_01 = ReferenceType_02;
ReferenceType_02[0] = 4;
ReferenceType_03[0] = 5;
System.out.println("ReferenceType_01 : "+ ReferenceType_01 + ", ReferenceType_02 : "+ ReferenceType_02 + ", ReferenceType_03 : " + ReferenceType_03);
System.out.println("ReferenceType_01 : "+ ReferenceType_01[0] + ", ReferenceType_02 : "+ ReferenceType_02[0] + ", ReferenceType_03 : " + ReferenceType_03[0]);
Primitive type Result
결과를 보게되면 Primitive type 경우 primitiveType_01 = primitiveType_02; 이런식으로 값을 대입한 후 primitiveType_02 의 값은 변경해도 primitiveType_01에게는 영향이 없는것을 확인 할 수있다.
primitiveType 변경 전
primitiveType 변경 후
하지만 Reference type의 경우 ReferenceType_01 = ReferenceType_02; 이런식으로 대입한 후 ReferenceType_02의 값을 변경하게 되면 ReferenceType_01도 같이 바뀌는것을 확인할 수있다. 이것이 바로 stack 영역에 heap의 위치를 가르키는 주소값은 저장하기때문에 발생하는 원리이다. ReferenceType의 출력중 첫번째줄과 세번째 줄을보면 내가 넣은값이 아닌 이상한 값이 들어가 있는것을 확인 할 수 있을것이다 .이게 바로 stack 영역에 저장된 heap의 주소값이다. 세번째 출력 결과를 보면 ReferenceType_01 와 ReferenceType_02의 주소값이 같은것을 확인 할 수있다. 따라서 둘은 같은 공간을 바라보고 있기 때문에 둘중 아무 변수의 내용물을 변경하더라고 둘 변수의 값이 모두 변하는 것이다.
referenceType 변경 전
referenceType 변경 후
여기까지 일다보면 한가지 의문이 들것이다.
과연 String은 무엇일까?
String은 Reference type이지만 Primitive type처럼 보인다 이것이 가능한 이유는 자바 에서 내부적으로 처리를 해주기 때문이다. 일단 이정도로 넘어가고 추후에 제대로 다뤄보겠다.
'Java' 카테고리의 다른 글
[JAVA] Spring Annotation @MapperScan이란? (0) | 2022.08.17 |
---|---|
[JAVA]Spring Boot 압축 파일 다운받기(Spring boot zip file download) (0) | 2022.05.09 |
[JAVA] @ReqeustBody와 @ResponseBody 란? (0) | 2022.02.12 |
[JAVA] DTO vs VO (0) | 2022.02.10 |
[JAVA]Mapper vs DAO (0) | 2022.02.08 |