-
Java 기본 타입(primitive type), 참조 타입(reference type, wrapper class) 사이의 차이점Backend/JAVA&JAVA8 2022. 5. 21. 20:32
Java는 변수의 유형을 따집니다.
그래서 Java에서는 어떠한 값을 대입하거나, 대입한 값을 넘기거나 그 값을 재 가공하려면 해당 자료가 어디에서 쓰이는 무슨 자료형인지 알아야 합니다.
갑자기 무슨 소리냐고요? 얼마 전에 있었던 한 사건에 대해 슬쩍 이야기한 후 오늘 주제에 대해서 말씀드리려고 합니다. 저는 요새 서버 단을 Spring + Java로 짜고 있는데요.
얼마 전 동료분께서 정말 기본적인 질문을 주셨는데 제가 대답을 못했습니다.
그 질문은 바로...'원시형과 참조형의 차이가 뭐예요?' 입니다.
(저의 포스팅에서는 원시형 == 기본형입니다만 혹시나 헷갈리실 분들을 위해서 앞으로는 원시형이라고 하겠습니다.)
'분명 공부했는데...ㅠ.ㅠ'라는 생각도 잠시...
어쨌거나 기억이 제대로 안 나면 내가 공부를 안 한 거나 마찬가지라는 생각이 들어서, 다시 검색하여 찾게 되었습니다. 조금 쉽게 이야기하면 원시 타입은 int, double, boolean 을 말하며, 참조 타입은 Integer, Double, Boolean 을 말합니다.
요즈음에는 autoBoxing, autoUnBoxing이 잘 되어있어서 개발자 입장에서는 크게 불편함이 없습니다.
*
Boxing이 뭐냐 구요? 이해를 돕기 위해 간단 하게만 다루어보겠습니다.
Boxing은 원시 자료형을 -> Wrapper Class로 변환하는 과정을 의미합니다.
코드로 살펴보겠습니다.
int menHeight = 173; Integer wrappedHeight = new Integer(menHeight);
위를 Boxing이라고 합니다.
그리고
Integer menHeight = new Integer(173); int men_height = menHeight.intValue();
위를 UnBoxing이라고 합니다.
그런데 위와 같이 코드를 작성하면 갑자기 intelliJ에서는 new Integer(173); 이 부분에 노란색 음영이 보이면서 removing 하라고 안내를 해줍니다.
이렇게 자동으로 값을 넣을 수 있는 것이 AutoBoxing입니다. AutoUnBoxing은 반대겠죠.
AutoBoxing과 AutoUnBoxing 은 원시형 타입과 그에 상응하는 Wrapper class 일 때만 일어납니다.
(다른 경우에 대입을 시도하면 컴파일 에러가 발생합니다)
Boxing에 대해 이야기하다가 이야기가 많이 옆길로 새게 되었는데요.
다시 원래의 주제로 돌아와서, 둘의 차이점에 대해서 다시 자세하게 살펴보도록 하겠습니다.
이 두 가지 타입에는 차이점이 있는데요.
정리해보면 ....
1.
원시 타입은 실제 값을 변수 안에 저장합니다.
참조 타입은 메모리 번지 수(객체에 접근하는 방법을 나타내는 비트가 들어있는 것입니다)를 값으로 가집니다.
2.
원시 타입은 산술 연산이 가능합니다.
참조 타입은 산술 연산이 불가능합니다
3.
원시 타입은 Null을 담을 수 없습니다.
참조 타입은 Null을 담을 수 있습니다.
4.
원시 타입은 Generic Type에서 사용할 수 없습니다.
참조 타입은 Generic Type에서 사용할 수 있습니다.
차이점은 위와 같습니다.
위 차이점들만 보면 원시 타입은 산술 연산을 할 수는 있지만 무언가가 조금 불편해 보입니다.
그렇다면, 어떠한 경우에 원시 타입을 사용할까요?
원시 타입은 성능 상의 이점이 있습니다.
원시 타입은 Stack Memory 에 존재하고,
참조 타입은 하나의 객체이기 때문에 Stack Memory 에는 참조 값만 있고 실제 값은 Heap Memory에 존재하게 됩니다. (객체는 Heap에서 생성됩니다. 그리고 그 객체를 참조하는 변수들이 StackMemory 에 있습니다)
그리고, 값을 필요로 할 때마다 Boxing 과 Unboxing의 과정을 거쳐야 하니 원시 타입과 비교해서 접근 속도 또한 느려지게 됩니다.
(만약 엄청 큰 숫자를 넘겨야 한다면 BigInteger와 같은 참조형이 더 좋을 것입니다)
마지막으로, 어떠한 경우에 참조 타입을 사용할까요?
위에서 설명드렸지만, 흔한 이유로 null로 변숫값을 초기화하고 싶을 때에 많이 사용합니다.
그리고 DB와 연동시 DTO 객체에 null이 필요한 경우 사용할 수 있습니다.
또한 매개변수로 객체가 요구될 때, 기본형이 아닌 객체로 저장해야 할 때, 객체 간의 비교가 필요할 때 등등이 있습니다.
긴 글 읽어주셔서 감사합니다!
'Backend > JAVA&JAVA8' 카테고리의 다른 글
Clean Code를 위해 지켜야 하는 몇 가지 사항들 (0) 2022.05.21 [JAVA8] group by (0) 2022.05.05 [JAVA8] Map to List, List to Map-2 / Map을 리스트로, 리스트를 맵으로-2 (0) 2022.05.05 [JAVA8] Map to List, List to Map-1 / Map을 리스트로, 리스트를 맵으로-1 (0) 2022.05.05 [JAVA8] What is different things between findAny and findFirst? / findAny와 findFirst의 차이점에 대하여 (0) 2022.05.05