저는 래퍼클래스가, Null을 처리할 수 있기 때문에, 더 범용성이 좋고, 유용하다고 생각했습니다..
하지만, 온보딩 과제를 진행할때, 매개변수를 사용할 때 래퍼클래스보단, 기본타입을 이용하는게 좋다는 피드백을 받았고,
이번 포스트이에는, 그 이유에대해서 생각해본 것을 정리해볼까 합니다..!
[목차]
- JAVA 자료형 종류와 차이점 (기본타입 자료형 vs 참조타입 자료형)
- Wrapper Class란
- Wrapper Class 특징
- String의 생성과 비교 방식
- Wrapper Class를 사용해야할 때
📌 Java의 자료형 2가지
1. 기본 타입 자료형 (Primitive Type)
- int, boolean, double, float 등등
2. 참조 타입 자료형 (Refernce Type)
- Integer, Boolean, String, Double 등등
자바에서 자료형의 타입은, 위와 같이 2가지가 존재합니다.
두 자료형의 가장 큰 차이점은, 아래와 같다고 생각합니다.
- 값을 저장하는가(기본타입), 주소를 참조하는가(참조타입)
- jvm내부에서 메모리가 어디 영역에 저장되는가 (stack - 기본형이 저장됨, heap - 객체들이 저장됨)
자바에서 객체들이 생성될 때는, 그 객체가 힙영역에 생성되어, 생성된 주소를 참조하게됩니다.
//생성되는 순간, heap 영역에 Car객체가 생성되고
// myCar 는 그 주소값을 참조합니다.
Car myCar = new Car()
📌 Wrapper Class
래퍼클래스도 마찬가지 입니다. 생성할 때 기본타입을 객체로 감싸서 생성주기 때문에 힙영역에 생성되고 그 주소값을 참조하는, 참조타입 자료형 입니다.
//래퍼클래스 또한 객체의 형식으로 기본타입을 감싸서 생성 -> 참조타입
Integer a = new Integer(1);
한마디로 정리하자면,
래퍼클래스란(Wrapper Class), 기본타입(primitive Type) 데이터를 객체로 다뤄야할 때, 참조 타입으로 다루기위해 객체로 감싸 다루는 것을, 래퍼클래스라고 합니다.
📌 Wrapper Class 특징
✨1. "==" 비교 연산 불가
- == 비교 연산자는 비교하는 2 값들이 같은지를 비교합니다.
- 기본타입에서는 값을 비교하고
- 참조타입에서는 참조된 주소를 비교해, 같은 객체인지를 확인합니다.
- 따라서, 두 객체의 값은 같더라도, 참조되는 주소가 다를 수 있기 때문에 == 연산이 의도와 다를 수 있습니다.
Integer a = new Integer(10);
Integer b = new Integer(10);
참조타입의 값을 비교하기 위해서는, equals 함수를 이용해야하며, 혹은 hascode() 함수를 사용해서 값을 비교할 수 있기도 합니다.
✨ 2. 래퍼클래스는 불변 객체 (Immutable)
래퍼클래스는, 불변 객체여서 한번 할당된 객체는 값이 변하지 않습니다.
우리가 수정이나 값을 변경할 때는, 객체의 값을 변경하는게 아닌, 새로운 값의 객체를 new 생성해서 반환받는 것 입니다.
📌 String 생성 과 비교
String 또한, 래퍼클래스입니다. 즉 참조형 데이터 타입인데
String은 특이하게 "==" 연산으로 비교를 하곤 합니다. 왜 String만 다를까요?
그 이유는 스트링의 생성과 연관이 있습니다.
📌 String 생성 방식
String의 생성 방식은 리터럴 방식과, 객체 생성 방식이 있습니다.
✨ 1. 리터럴 방식
고정 데이터 값을 생성하는 방식으로 위처럼 String 변수에 값을 대입해주는 것을 말합니다.
String은 참조 데이터 타입이지만, 그 객체의 주소가 jvm heap 메모리 영역 내부에, 별도의 String Context Pool 영역을 가집니다.
String이 리터럴 방식으로 생성될 때, String 내부에서 Intern() 메소드가 호출됩니다.
Intern() 메소드는 그 값이 String pool 에 존재하면, 새로운 객체를 생성하지 않고, String pool에 미리 존재하는,
문자열 객체의 주소값을 할당해 줍니다.
따라서, String이 리터럴 방식으로 생성되면, 래퍼 클래스임에도 불구하고, 같은 주소값을 할당받게 되는 것입니다.
✨ 2. 객체 생성 방식 (new 연산자)
하지만 리터럴 방식이 아닌 new 연산자로 새로운 객체를 할당한다면,
참조 타입 객체 생성과 똑같습니다.
값이 같더라도 다른 객체를 생성해주기 때문에, 주소값이 달라 "=="비교를 할 수 없습니다.
📌 Wrapper Class 를 사용해야할 때
본론입니다.
그렇다면, 언제 Wrapper Class를 사용해야 할까요
물론 정답은 없지만, 저는 "Null 값을 다뤄주어야할 때" 라고 생각합니다.
Wrapper Class로 자료형을 다루면 기본 타입보다 2가지 정도를 더 잘 할 수 있습니다
1) Null 값을 받을 수 있다.
2) toString() 메소드로, 문자열로 보다 쉽게 변환할 수 있다.
✨ Wrapper Class 의 Null 다루기
래퍼 클래스를 사용하면, 데이터 타입을 객체로 감싸주어(Boxing) 안에서 데이터를 관리할 수 있고, 그렇기 때문에 null을 데이터 값으로 받을 수 있습니다.
✨ Wrapper Class 의 Null 은 불친절하다.
null 을 데이터 값으로 받을 수 있다는 것, 사용자로부터 들어온 값이 Null인지, 제대로 들어왔는지 바로바로 파악할 수 없다는 것입니다.
즉, Null을 한번 더 체크해주어야하는, 불편함이 있습니다.
✨ Wrapper Class가 사용될 때
따라서, 래퍼클래스는, 어쩔 수 없이 Null을 다루어야할 때만 사용하는 게 좋습니다.
1) DB에 값이 저장될 때
- DB에는 값이 null로 들어갈 수 있기 때문에, 유연하게 값을 받을 필요가 있습니다.
- 디비 테이블에 Null이 들어갔는지 아닌지, 판단할 수 없을 때, Wrapper Class를 사용하면 유용합니다.
➡️ 하지만, null을 허용하지 않는 컬럼일 경우는, 똑같이 기본 데이터타입으로 지정
(예외)
2) request로도 null이 들어올 때
- 이때 또한 Requeset 들어오는 값이 Null일 수 있기에 WrapperClass로 받아 줄 수있긴 합니다.
- 하지만, request같은 경우는 -> @validate, @NotNull같은 거로, 사전에 차단하는게 좋을지도...?
따라서, Null을 바로바로 파악할 수 있는 (NullPointException을 떨궈버리는) 기본 타입을 잘 사용하자!!
'Java > 클린 코딩 (with OOP)' 카테고리의 다른 글
4. 정규표현식이란, java 정규식 구성 및 가이드 + [JAVA에서 성능 높이기] (0) | 2022.06.11 |
---|---|
2. 주석 사용 지양해야하는 이유 - 클린 코드 4장 (0) | 2022.06.07 |
1. 자바 네이밍 규칙 (java 네이밍 컨벤션) (5) | 2022.06.02 |
0. Google style convention 적용하기 (0) | 2022.06.01 |
[JAVA] 자바 클린 코딩 하기 - 객체지향이기위해 지켜야하는 것들 (0) | 2022.06.01 |