[Java ]개념노트 40 Wrapper 클래스 이해하기

[Java 개념노트 40] Wrapper 클래스 이해하기

안녕하세요. Java 개념노트 시리즈 마흔 번째 글입니다.

지난 글에서는 문자열을 효율적으로 조립하고 수정할 때 사용하는 StringBuilder에 대해 정리했습니다. 이번 글에서는 기본 자료형을 객체처럼 다룰 수 있게 해주는 Wrapper 클래스에 대해 알아보겠습니다.

자바에는 int, double, boolean 같은 기본 자료형이 있습니다. 그런데 어떤 상황에서는 기본 자료형을 객체처럼 다뤄야 할 때가 있습니다. 이때 사용하는 것이 Wrapper 클래스입니다.


1. Wrapper 클래스란?

Wrapper 클래스는 기본 자료형 값을 객체로 감싸서 사용할 수 있게 해주는 클래스입니다.

여기서 wrapper는 “감싸는 것”이라는 뜻입니다. 즉, int 값을 Integer 객체로 감싸고, double 값을 Double 객체로 감싸는 식입니다.

쉽게 말하면
Wrapper 클래스는 기본 자료형을 객체처럼 사용할 수 있도록 감싸주는 클래스입니다.

2. 기본 자료형과 Wrapper 클래스

자바의 기본 자료형에는 각각 대응되는 Wrapper 클래스가 있습니다.

기본 자료형 Wrapper 클래스 예시
byte Byte Byte value
short Short Short value
int Integer Integer value
long Long Long value
float Float Float value
double Double Double value
char Character Character value
boolean Boolean Boolean value

기억하기
int의 Wrapper 클래스는 Int가 아니라 Integer입니다. char의 Wrapper 클래스도 Char가 아니라 Character입니다.

3. Wrapper 클래스가 필요한 이유

기본 자료형은 값 자체를 저장하므로 가볍고 빠릅니다. 그런데 자바에서는 객체가 필요한 상황이 있습니다.

  • 컬렉션에 기본 자료형 값을 넣을 때
  • 제네릭 타입으로 값을 다룰 때
  • null 값을 표현해야 할 때
  • 문자열을 숫자로 변환할 때
  • 기본 자료형 관련 유틸 메서드를 사용할 때

예를 들어 ArrayList 같은 컬렉션에는 기본 자료형을 직접 타입으로 사용할 수 없습니다.

// ArrayList<int> numbers; // 오류 발생

대신 Wrapper 클래스인 Integer를 사용해야 합니다.

ArrayList<Integer> numbers;

4. int와 Integer의 차이

int는 기본 자료형이고, Integer는 클래스입니다.

구분 int Integer
종류 기본 자료형 참조 자료형, 클래스
저장 대상 값 자체 정수 값을 감싼 객체
null 저장 불가능 가능
컬렉션 타입 직접 사용 불가 사용 가능
예시 int number = 10; Integer number = 10;

5. 박싱이란?

박싱은 기본 자료형 값을 Wrapper 클래스 객체로 감싸는 것을 말합니다.

int number = 10;

Integer wrapperNumber = Integer.valueOf(number);

위 코드에서는 int10Integer 객체로 감쌌습니다. 이것이 박싱입니다.

int 10
  ↓ 박싱
Integer 객체

6. 언박싱이란?

언박싱은 Wrapper 클래스 객체에서 기본 자료형 값을 꺼내는 것을 말합니다.

Integer wrapperNumber = Integer.valueOf(10);

int number = wrapperNumber.intValue();

Integer 객체 안에 들어 있던 정수 값을 int로 꺼냈습니다. 이것이 언박싱입니다.

Integer 객체
  ↓ 언박싱
int 10

7. 오토박싱

자바에서는 기본 자료형 값을 Wrapper 클래스에 대입할 때 자동으로 박싱을 해줍니다. 이것을 오토박싱이라고 합니다.

Integer number = 10;

위 코드는 내부적으로 다음과 비슷하게 동작합니다.

Integer number = Integer.valueOf(10);

개발자가 직접 Integer.valueOf()를 쓰지 않아도 자바가 자동으로 감싸줍니다.

핵심 포인트
오토박싱은 기본 자료형 값이 자동으로 Wrapper 객체로 변환되는 기능입니다.

8. 오토 언박싱

Wrapper 객체를 기본 자료형 변수에 대입하면 자바가 자동으로 값을 꺼내줍니다. 이것을 오토 언박싱이라고 합니다.

Integer wrapperNumber = 10;

int number = wrapperNumber;

위 코드는 내부적으로 다음과 비슷하게 동작합니다.

int number = wrapperNumber.intValue();

Wrapper 객체에서 값을 자동으로 꺼내 기본 자료형 변수에 저장한 것입니다.

9. 오토박싱과 오토 언박싱 예제

오토박싱과 오토 언박싱을 함께 사용하는 예제를 보겠습니다.

public class Main {
    public static void main(String[] args) {
        Integer a = 10;  // 오토박싱
        int b = a;       // 오토 언박싱

        System.out.println(a);
        System.out.println(b);
    }
}

실행 결과는 다음과 같습니다.

10
10

겉으로 보기에는 자연스럽게 대입되는 것처럼 보이지만, 내부적으로는 박싱과 언박싱이 자동으로 일어납니다.

10. Wrapper 객체로 연산하기

Wrapper 클래스 객체도 기본 자료형처럼 연산에 사용할 수 있습니다. 이때 오토 언박싱이 일어납니다.

public class Main {
    public static void main(String[] args) {
        Integer a = 10;
        Integer b = 20;

        int result = a + b;

        System.out.println(result);
    }
}

실행 결과는 다음과 같습니다.

30

a + b를 계산할 때 Integer 객체가 자동으로 int 값으로 언박싱되어 연산됩니다.

11. null과 Wrapper 클래스

기본 자료형은 null을 가질 수 없습니다. 하지만 Wrapper 클래스는 참조 자료형이므로 null을 가질 수 있습니다.

Integer number = null;

이 특성은 값이 없음을 표현해야 할 때 유용할 수 있습니다. 예를 들어 아직 점수가 입력되지 않은 상태를 null로 표현할 수 있습니다.

Integer score = null;

if (score == null) {
    System.out.println("점수가 아직 입력되지 않았습니다.");
}

12. null 언박싱 주의하기

Wrapper 객체가 null인 상태에서 기본 자료형으로 언박싱하려고 하면 오류가 발생할 수 있습니다.

Integer number = null;

int value = number; // 오류 발생 가능

number는 실제 Integer 객체를 가리키지 않습니다. 그런데 int로 꺼내려고 하면 NullPointerException이 발생할 수 있습니다.

주의
Wrapper 객체가 null일 수 있다면 언박싱 전에 반드시 null 여부를 확인하는 것이 안전합니다.

13. 문자열을 숫자로 바꾸기

Wrapper 클래스는 문자열을 숫자로 바꾸는 메서드를 제공합니다. 가장 자주 사용하는 것은 parseInt(), parseDouble()입니다.

String text = "100";

int number = Integer.parseInt(text);

System.out.println(number + 20);

실행 결과는 다음과 같습니다.

120

문자열 "100"이 정수 100으로 변환되었기 때문에 숫자 연산이 가능합니다.

14. parseDouble() 예제

실수 문자열은 Double.parseDouble()을 사용해서 double 값으로 바꿀 수 있습니다.

String text = "3.14";

double number = Double.parseDouble(text);

System.out.println(number + 1.0);

실행 결과는 다음과 같습니다.

4.140000000000001

실수 연산은 내부 표현 방식 때문에 소수점 결과가 약간 길게 나올 수 있습니다. 이 부분은 나중에 숫자 처리와 BigDecimal을 배울 때 더 자세히 이해할 수 있습니다.

15. 문자열 변환 실패

숫자로 바꿀 수 없는 문자열을 변환하려고 하면 오류가 발생합니다.

String text = "Java";

int number = Integer.parseInt(text); // 오류 발생

"Java"는 숫자 형태가 아니기 때문에 정수로 바꿀 수 없습니다. 이런 경우 NumberFormatException이 발생할 수 있습니다.

16. valueOf() 메서드

valueOf()는 문자열이나 기본 자료형 값을 Wrapper 객체로 변환할 때 사용합니다.

Integer number1 = Integer.valueOf(100);
Integer number2 = Integer.valueOf("200");

System.out.println(number1);
System.out.println(number2);

실행 결과는 다음과 같습니다.

100
200

Integer.parseInt()는 기본 자료형 int를 반환하고, Integer.valueOf()Integer 객체를 반환합니다.

17. parseInt()와 valueOf() 차이

parseInt()valueOf()는 비슷해 보이지만 반환 타입이 다릅니다.

메서드 반환 타입 예시
Integer.parseInt("100") int 기본 자료형 정수 반환
Integer.valueOf("100") Integer Integer 객체 반환
Double.parseDouble("3.14") double 기본 자료형 실수 반환
Double.valueOf("3.14") Double Double 객체 반환

18. 숫자를 문자열로 바꾸기

숫자를 문자열로 바꾸는 방법은 여러 가지가 있습니다.

int number = 100;

String text1 = String.valueOf(number);
String text2 = Integer.toString(number);
String text3 = number + "";

System.out.println(text1);
System.out.println(text2);
System.out.println(text3);

실행 결과는 다음과 같습니다.

100
100
100

보통은 의도가 명확한 String.valueOf(number)Integer.toString(number)을 사용하면 좋습니다.

19. Wrapper 클래스의 상수

Wrapper 클래스에는 최댓값과 최솟값 같은 상수가 들어 있습니다.

System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);

System.out.println(Double.MAX_VALUE);
System.out.println(Double.MIN_VALUE);

실행 결과는 환경에 따라 같은 정해진 값이 출력됩니다. 예를 들어 Integer.MAX_VALUE는 int가 가질 수 있는 가장 큰 값입니다.

2147483647
-2147483648

20. Wrapper 객체 비교 주의하기

Wrapper 객체를 비교할 때도 문자열처럼 ==보다 equals()를 사용하는 것이 안전합니다.

Integer a = new Integer(100);
Integer b = new Integer(100);

System.out.println(a == b);
System.out.println(a.equals(b));

실행 결과는 다음과 같습니다.

false
true

==는 두 참조변수가 같은 객체를 가리키는지 비교합니다. equals()는 값이 같은지 비교합니다.

주의
Wrapper 객체의 값을 비교할 때는 참조 비교인 ==보다 equals()를 사용하는 것이 안전합니다.

21. 컬렉션에서 Wrapper 클래스 사용하기

컬렉션은 객체를 저장하는 구조입니다. 그래서 기본 자료형을 직접 타입으로 사용할 수 없고 Wrapper 클래스를 사용해야 합니다.

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>();

        numbers.add(10);
        numbers.add(20);
        numbers.add(30);

        for (int i = 0; i < numbers.size(); i++) {
            System.out.println(numbers.get(i));
        }
    }
}

실행 결과는 다음과 같습니다.

10
20
30

numbers.add(10)에서 10은 자동으로 Integer로 오토박싱되어 저장됩니다.

22. Wrapper 클래스 전체 예제

이번에는 문자열 변환, 오토박싱, 오토 언박싱, null 체크를 함께 사용하는 예제를 보겠습니다.

public class Main {
    public static void main(String[] args) {
        String scoreText = "90";

        int score = Integer.parseInt(scoreText);

        Integer wrapperScore = score;

        if (wrapperScore != null) {
            int result = wrapperScore + 10;
            System.out.println("최종 점수: " + result);
        }

        String resultText = String.valueOf(wrapperScore);

        System.out.println("문자열 점수: " + resultText);
        System.out.println("int 최댓값: " + Integer.MAX_VALUE);
    }
}

실행 결과는 다음과 같습니다.

최종 점수: 100
문자열 점수: 90
int 최댓값: 2147483647

23. Wrapper 클래스 사용 시 자주 하는 실수

Wrapper 클래스를 처음 배울 때는 아래와 같은 실수를 자주 합니다.

실수 문제점 해결 방법
ArrayList<int> 사용 기본 자료형은 제네릭 타입으로 직접 사용 불가 ArrayList<Integer> 사용
null Wrapper 객체를 언박싱 NullPointerException 발생 가능 언박싱 전 null 체크
숫자가 아닌 문자열을 parse NumberFormatException 발생 가능 변환 전 문자열 형식 확인
Wrapper 객체를 ==로 비교 참조 비교가 되어 의도와 다를 수 있음 equals() 사용
박싱과 언박싱을 과도하게 반복 불필요한 변환으로 비효율 가능 단순 계산은 기본 자료형 사용

24. 직접 연습해보기

아래 코드를 직접 작성하고 실행해보세요.

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        String[] scoreTexts = {"90", "80", "70"};

        ArrayList<Integer> scores = new ArrayList<>();

        for (int i = 0; i < scoreTexts.length; i++) {
            int score = Integer.parseInt(scoreTexts[i]);
            scores.add(score);
        }

        int sum = 0;

        for (int i = 0; i < scores.size(); i++) {
            sum += scores.get(i);
        }

        double average = (double) sum / scores.size();

        System.out.println("총합: " + sum);
        System.out.println("평균: " + average);

        Integer maxScore = Integer.MAX_VALUE;
        System.out.println("int 최댓값: " + maxScore);
    }
}

실행 결과는 다음과 같습니다.

총합: 240
평균: 80.0
int 최댓값: 2147483647

25. 이번 글 정리

이번 글에서는 기본 자료형을 객체처럼 다루는 Wrapper 클래스에 대해 정리했습니다. 핵심 내용은 다음과 같습니다.

  • Wrapper 클래스는 기본 자료형을 객체로 감싸는 클래스이다.
  • int의 Wrapper 클래스는 Integer이다.
  • char의 Wrapper 클래스는 Character이다.
  • 기본 자료형 값이 Wrapper 객체로 변환되는 것을 박싱이라고 한다.
  • Wrapper 객체에서 기본 자료형 값을 꺼내는 것을 언박싱이라고 한다.
  • 오토박싱과 오토 언박싱은 자바가 자동으로 처리해주는 변환이다.
  • Wrapper 클래스는 null을 가질 수 있다.
  • null Wrapper 객체를 언박싱하면 오류가 발생할 수 있다.
  • 문자열을 숫자로 바꿀 때 parseInt(), parseDouble() 등을 사용할 수 있다.
  • valueOf()는 Wrapper 객체를 반환한다.
  • 컬렉션에서는 기본 자료형 대신 Wrapper 클래스를 사용한다.
  • Wrapper 객체의 값 비교에는 equals()를 사용하는 것이 안전하다.

한 줄 요약
Wrapper 클래스는 기본 자료형을 객체처럼 다루기 위해 사용하는 클래스이며, 박싱과 언박싱, 문자열 숫자 변환, 컬렉션 사용에서 자주 등장합니다.

다음 글 예고
다음 글에서는 [Java 개념노트 41] Math 클래스 이해하기라는 주제로 최댓값, 최솟값, 반올림, 랜덤 숫자 등 자주 쓰는 수학 기능을 정리해보겠습니다.

GWDEVELBlog Java 개념노트 시리즈