기본 패턴
// 기본 타입 ↔ 래퍼 클래스
int primitive = 42;
Integer boxed = primitive; // 오토박싱 — 컴파일러가 Integer.valueOf(42)로 변환
int unboxed = boxed; // 언박싱 — 컴파일러가 boxed.intValue()로 변환
// 컬렉션에는 래퍼 클래스 필요
List<Integer> numbers = new ArrayList<>();
numbers.add(10); // 오토박싱
int n = numbers.get(0); // 언박싱설명
기본 타입과 래퍼 클래스가 공존하는 이유
Java의 기본 타입(int, double, boolean 등)은 객체가 아닙니다. 값만 담는 가볍고 빠른 저장 단위입니다. 반면 컬렉션(List<T>, Map<K, V>)은 제네릭의 타입 매개변수 자리에 객체만 올 수 있습니다.
이 간극을 메우기 위해 각 기본 타입에 대응하는 래퍼 클래스가 존재합니다: int → Integer, double → Double, boolean → Boolean 등. 오토박싱은 컴파일러가 int를 Integer로(박싱), Integer를 int로(언박싱) 자동 변환하는 기능입니다.
// 기본 타입 — 객체 아님, 컬렉션 불가
int x = 10;
// List<int> list = ...; // 컴파일 오류
// 래퍼 클래스 — 객체, 컬렉션 가능
List<Integer> list = new ArrayList<>();
list.add(10); // 오토박싱: int 10 → Integer 10오토박싱의 비용과 Integer 캐시
오토박싱은 편리하지만 힙 할당이 일어납니다. 루프 안에서 반복적으로 박싱/언박싱이 일어나면 불필요한 객체가 대량 생성됩니다.
한 가지 중요한 세부사항: Java는 -128 ~ 127 범위의 Integer 객체를 캐시합니다. 이 범위 안에서는 ==로 비교해도 true가 나오지만, 범위 밖에서는 다른 객체가 생성되어 ==가 false가 됩니다. Integer 값 비교는 항상 equals()를 써야 합니다.
// ⚠ Integer 캐시 범위 내 — == 가 true
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true (캐시된 같은 객체)
// ⚠ Integer 캐시 범위 밖 — == 가 false
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false (다른 객체)
System.out.println(c.equals(d)); // true (값 비교)언박싱과 NullPointerException
Integer 같은 래퍼 클래스는 null을 가질 수 있습니다. null인 래퍼를 기본 타입에 대입하면 언박싱이 일어나고 NullPointerException이 발생합니다. 특히 메서드 반환값이나 Map에서 가져온 값을 기본 타입 변수에 바로 대입할 때 주의해야 합니다.
Map<String, Integer> scores = new HashMap<>();
// "Alice"는 map에 없음
// ❌ 없는 키 → null 반환 → int 언박싱 → NullPointerException
int score = scores.get("Alice"); // NullPointerException
// ✅ getOrDefault로 기본값 지정
int score = scores.getOrDefault("Alice", 0); // 0
// ✅ 또는 null 체크 후 언박싱
Integer value = scores.get("Alice");
if (value != null) {
int s = value; // 안전한 언박싱
}빠른 정리
| 상황 | 선택 |
|---|---|
| 기본 타입 컬렉션 저장 | 래퍼 클래스 (Integer, Double 등) |
| 성능 민감한 수치 연산 | 기본 타입 (int, double) |
| 래퍼 값 비교 | equals() (== 금지) |
| Map에서 가져온 값 언박싱 | getOrDefault() 또는 null 체크 후 |
| 유틸리티 메서드 | Integer.parseInt(), Integer.max() 등 |
주의할 점
null인 래퍼 타입을 기본 타입 변수에 대입하면 언박싱 시 NullPointerException이 발생합니다. 반환 타입이 래퍼 클래스인 메서드는 항상 null 가능성을 고려하세요.
Integer getCount() {
return null; // null 반환 가능
}
// ❌ 직접 언박싱 — NullPointerException
int count = getCount();
// ✅ null 체크 후 언박싱
Integer raw = getCount();
int count = (raw != null) ? raw : 0;
// ✅ Optional 활용
int count = Optional.ofNullable(getCount()).orElse(0);참고 링크
1 sources