1. 소개
Java에는 두 가지 데이터 계열이 있습니다. 첫째 — 기본형: int, char, double, boolean 등입니다. 이들은 단순하고 빠릅니다. 값이 메모리 셀에 직접 저장됩니다. 둘째 — 참조형, 즉 객체입니다. 변수에는 객체가 메모리에 위치한 곳을 가리키는 참조가 저장됩니다.
때로는 기본형을 객체처럼 사용해야 할 때가 있습니다. 하지만 기본형은 원래 객체가 아닙니다. 이런 경우에 특별한 래퍼 클래스가 도움이 됩니다.
래퍼 타입은 기본형 값을 내부에 담아 객체처럼 다루게 해 주는 클래스입니다. 예를 들어 int에는 Integer, double에는 Double, char에는 Character, boolean에는 Boolean이 있습니다. 이러한 클래스들은 다음과 같은 메서드를 제공합니다: Integer.parseInt(), Double.isInfinite(), Character.isLetter(), Boolean.parseBoolean() 등.
Integer 객체를 int 기본형에서 얻는 예:
// 기본형
int a = 10;
// 래퍼 객체
Integer b = Integer.valueOf(10);
변수 a에는 숫자 10 자체가 저장됩니다. 반면 변수 b에는 내부에 10을 담은 객체에 대한 참조가 저장됩니다.
2. 왜 래퍼가 필요한가
기본형은 항상 구체적인 값이며 null로 만들 수 없습니다. 객체는 존재하지 않을 수도 있고 빈 값을 저장할 수 있습니다 — “알 수 없음”이나 “없음”을 표시해야 할 때 유용합니다.
기본형에는 메서드가 없습니다. 숫자에 대해 x.toString() 같은 호출을 할 수 없습니다. 래퍼는 이러한 기능을 제공합니다. 예를 들어 Integer.parseInt("123")는 문자열을 숫자로 변환하고, 숫자는 toString()으로 문자열로 바꿀 수 있습니다.
요약: 객체가 필요한 곳에서 래퍼가 필요합니다 — null을 저장하고, 메서드를 호출하고, 오직 객체만 받는 API(예: List<Integer> 같은 컬렉션)에 값을 전달해야 할 때.
래퍼 타입 전체 목록
| 기본형 | 래퍼 클래스 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. 박싱과 언박싱
래퍼 객체를 수동으로 생성하면, 기본형 값을 객체 안으로 ‘박싱’합니다:
int primitive = 42;
Integer wrapper = Integer.valueOf(primitive); // 박싱
다시 기본형 값을 꺼내려면 — ‘언박싱’ — 예를 들어 intValue()를 사용합니다:
Integer wrapper = Integer.valueOf(42);
int primitive = wrapper.intValue(); // 언박싱
오토박싱 (Autoboxing)
기본형을 래퍼 변수에 대입하면 컴파일러가 자동으로 valueOf() 호출을 추가합니다:
int a = 10;
Integer b = a; // 오토박싱 (Integer.valueOf(a))
언박싱 (Unboxing)
반대 상황 — 기본형이 필요한 곳에서 래퍼 객체가 사용될 때:
Integer c = 20;
int d = c; // 언박싱 (c.intValue())
int a = 10; // 기본형
Integer b = a; // 오토박싱
Integer c = Integer.valueOf(20);
int d = c; // 언박싱
4. 주의할 점
래퍼 비교. 객체에 대해 == 연산자는 값을 비교하는 것이 아니라 참조를 비교합니다:
Integer m = 200;
Integer n = 200;
System.out.println(m == n); // false — 서로 다른 객체이기 때문
Java는 -128부터 127 범위의 숫자 래퍼를 캐시하므로, 어떤 때는 ==가 true를, 어떤 때는 false를 반환합니다. 값 비교에는 항상 equals()를 사용하세요:
Integer x = 100;
Integer y = 100;
System.out.println(x == y); // true — 캐시에 들어감
System.out.println(x.equals(y)); // true — 값을 비교
언박싱 시 NullPointerException. 래퍼가 null인데 언박싱하려 하면 예외가 발생합니다:
Integer value = null;
int primitive = value; // 오류! NullPointerException
성능과 메모리. 래퍼는 기본형보다 느리고 더 많은 메모리를 차지합니다. 핫한 코드 경로나 큰 숫자 배열을 다룰 때는 기본형을 선택하세요.
5. 예시
Integer와 Double 사용 예
문자열을 숫자로 변환:
String text = "123";
int number = Integer.parseInt(text);
System.out.println(number); // 123
부동소수 특수 값 확인:
double d = 1.0 / 0;
System.out.println(Double.isInfinite(d)); // true
double nan = 0.0 / 0.0;
System.out.println(Double.isNaN(nan)); // true
Character 사용 예
char는 한 문자를 저장하며, 래퍼 Character는 편리한 검사 메서드를 제공합니다:
char ch = 'A';
Character wrapper = ch; // 오토박싱
System.out.println(Character.isLetter(ch)); // true
System.out.println(Character.isDigit(ch)); // false
System.out.println(Character.toLowerCase(ch)); // 'a'
Boolean 사용 예
기본형 boolean은 true/false만 가질 수 있습니다. 래퍼 Boolean은 null도 저장할 수 있습니다:
Boolean flag = null; // 허용됨
flag = Boolean.TRUE; // 특수 상수
System.out.println(flag); // true
문자열을 논리값으로 변환:
String s1 = "true";
String s2 = "false";
boolean b1 = Boolean.parseBoolean(s1);
boolean b2 = Boolean.parseBoolean(s2);
System.out.println(b1); // true
System.out.println(b2); // false
GO TO FULL VERSION