JAVA

[JAVA] 래퍼 클래스(Wrapper Class) 정리

tudamoa 2025. 2. 16. 01:32

래퍼 클래스(Wrapper Class) 란?

한마디로, 기본 타입을 객체로 다룰 수 있게 해주는 클래스이다.

 

차근차근 설명하자면, 래퍼 클래스는  '포장지' 라는 뜻의 'Wrapper' 라는 단어의
 의미에서 알 수 있듯 선물처럼 무언가를 포장하는 클래스이다.

 

선물은 내가 고른 물건을 이쁘게 주기 위해 포장하는데,

래퍼클래스는 정확히 무엇을, 왜, 어떻게 포장할까?

 



무엇을 포장할까?

자바는 기본 타입(Primitive type)참조 타입(Reference type)으로 나누어진다.
이 중 래퍼 클래스기본 타입(Primitive type)을 포장하여 객체를 만든다.

 

기본 타입을 왜 포장하는지 알기 전, 기본 타입과 참조 타입에 대한 이해가 필요하다.

 

1. 기본 타입(Primitive type) 

  타입 기본값
     정수형 byte 0
short 0
int 0
long 0L
     실수형 float 0.0F
double 0.0
     문자형 char '\u0000'
     논리형 boolean false

 

기본 타입은 int, float, boolean 같이
계산을 위해 실제 값을 저장하고 연산하는 데 사용된다.

 

기본 타입은 다음과 같은 특징을 가지고 있다.

 

1. 기본값이 정해져 있어서 null 값을 가질 수 없다.

2. 저장공간에 실제 값을 저장한다.

3. 소문자로 시작된다.

4. 메모리의 스택에 저장된다.

 

2. 참조 타입(Reference type)

타입 기본값
배열(array)       null
클래스(class)
인터페이스(interface)
열거(enum)

 

참조 타입은 클래스, 배열 , 열거 타입 등
객체로 사용할 수 있는 타입을 지칭한다.

 

참조 타입은 다음과 같은 특징을 가지고 있다.

 

1. 자료가 저장된 공간의 주소를 저장한다.
2. null 값을 가질 수 있다.

3. 메모리의 힙에 실제 값을 저장하고, 주소값은 스택에 저장한다.


왜 포장할까?

각 타입의 특징에서 이유를 알 수 있는데, 
래퍼 클래스
는 객체를 지향하는 자바 언어에서
객체로 사용하지 못하는 기본 타입(Primitive type)을 객체로 사용하기 위해서다.

 

자바 프로그래밍을 하다보면 데이터를 객체 형태로 사용해야 하는 경우가 종종 있다.

 

1. null 값을 저장해야 할 때

만약, 데이터베이스에서 숫자 값을 가져올 때 null값이 있다면 기본 타입으로 저장할 시 오류가 날 수 있다.

이때, 래퍼 클래스를 사용하면 null값을 저장하여도 오류가 발생하지 않는다.

Integer num = null; // 래퍼클래스 - 가능
int num = null; // 기본 타입 - 불가능

 

2. 컬렉션 및 제네릭에서 기본 타입을 저장해야 할 때

ArrayList와 Vector같은 컬렉션은 기본 타입을 직접 저장할 수 없기 때문에 래퍼 클래스로 저장을 해야한다.

기본 타입은 메모리의 스택(stack)에 저장되는 반면, 컬렉션은 객체가 저장되어 있는 힙(heap)을 가르키기 때문이다.

그래서 래퍼클래스를 통해서만 사용할 수 있다.

//  자료형을 선언할 때 쓰이는 < > 기호가 제네릭이다. 이 괄호 안에는 객체 타입만 들어갈 수 있다.

import java.util.Vector;
import java.util.ArrayList;

public class Example {
    public static void main(String[] args) {
        // Vector<int> vector = new Vector<>(); // 기본 타입 - 불가능
        // ArrayList<int> list = new ArrayList<>(); // 기본 타입 - 불가능
        
        Vector<Integer> vector = new Vector<>(); // 래퍼클래스 - 가능 
        vector.add(10); // int -> Integer 오토박싱
        vector.add(20);
        
        ArrayList<Integer> list = new ArrayList<>(); // 래퍼클래스 - 가능
        list.add(100);  // int -> Integer 오토박싱
        list.add(200);

        System.out.println(vector.get(0));
        System.out.println(list.get(0));
    }
}

 

3. 메서드에서 객체를 인자로 받거나 리턴할 때

메서드의 매개변수나 반환값이 객체여야 하는 경우 기본 타입을 직접 사용할 수 없다.

하지만, 자바의 오토박싱(Auto-Boxing) 기능 덕분에 자동으로 래퍼 클래스로
변환되어 자연스럽게 기본 타입을 삽입할 수 있다.

// 오토박싱에 대해선 아래에서 설명

public class Example {
    public static void Number(Object obj) {  
        System.out.println(obj);
    }

    public static void main(String[] args) {
        Number(10);  // int → Integer 변환 오토박싱 덕분에 가능
        Number(3.14); // double → Double 변환 오토박싱 덕분에 가능
        Number("Hello"); // String은 원래 객체라 가능
    }
}

 


어떻게 포장할까?

위에 예시를 들 때 몇몇은 나왔지만, 각 기본 타입을 포장하기 위한 포장지(래퍼 클래스)는 다음과 같다.

기본 타입 래퍼 클래스
int Integer
char Character
byte Byte
short Short
long Long
float Float
double Double
boolean Boolean

 

 

거의 기본 타입에서 대문자로 조금 바뀐 정도이다.

특정 기본 타입을 객체로 만들기 위해서 해당하는 래퍼 클래스를 사용하면 된다.

Integer number = new Interger(1); // 구식 코드
Integer number = Integer.valueOf(1); // 최신 코드
// number라는 래퍼 클래스를 Integer 형식으로 생성하고 그 값을 1로 할당

 

이때, 기본 타입래퍼 클래스 간의 변환을 박싱(Boxing)언박싱(UnBoxing) 이라고 한다.

포장을 해버렸지만, 안에 물건을 더 넣고 싶으면 포장을 다시 뜯어야 하듯이.. 

객체로 만들었지만 값을 더하거나 변환 시키고 싶다면 언박싱을 해야한다.

int num = 1;
Integer number = Integer.valueOf(num); // 기본 타입 -> 래퍼클래스 | 박싱(Boxing)

num = number.intValue(); // 래퍼클래스 -> 기본 타입 | 언박싱(UnBoxing)

num = num + 1; // 물건 추가 | 값 변경
number = Integer.valueOf(num); // 기본 타입 -> 래퍼클래스 | 박싱(Boxing)

 

하지만, JDK 1.5 이상 버전 부터는 박싱과 언박싱을 일일이 할 필요 없이 자동으로 처리해주는

오토박싱(Auto-Boxing)과 오토언박싱(Auto-UnBoxing)을 지원한다.

// 이 기능은 큰 차이는 아니지만, 속도 면에서 좋지 못하기 때문에 무조건적인 사용은 지양하는 게 좋다.

import java.util.ArrayList;

public class Example {
    public static void main(String[] args) {
    	int n = 100;
        int m = 200;
        
        ArrayList<Integer> list = new ArrayList<>();
        list.add(n);  // Integer만 더할 수 있는 ArrayList에 int를 더해도 오류 X
        list.add(m);  // 자바 내부에서 자동으로 박싱하여 더했기 때문이다.

        int num1 = list.get(0); // 위와 같이 Integer -> int로 자동으로 언박싱하여 값을 할당했다.
        int num2 = list.get(1);
        
        System.out.println(num1); // 100
        System.out.println(num2); // 200
    }
}

 

public class Example {
    public static void main(String[] args) {
        Integer num1 = 1; // 오토박싱
        Integer num2 =  Integer.valueOf(3); // 박싱

        int int1 = num1; // 오토언박싱
        int int2 = num2.intValue();    // 언박싱

// 오토 언박싱하여 연산하고, 다시 오토박싱하여 저장
        Integer res1 = num1 + num2;
        Integer res2 = int1 - int2;
        int res3 = num1 * int2;    
        
        System.out.println(res1); // 4
        System.out.println(res2); // -2
        System.out.println(res3); // 3
    }
}

 

래퍼 클래스와 기본 타입의 비교

 

다른 비교 연산은 문제가 되지 않지만, 동등 연산에서는 문제가 생길 수도 있다.

객체에서 동등 연산자 == 은 객체의 값을 비교하는 게 아닌 객체의 주소값을 비교하기 때문이다.

Integer num1 = Integer.valueOf(10);
Integer num2 = Integer.valueOf(1000);
Integer num3 = Integer.valueOf(10);

System.out.println(num1 == num3);      // false | 값이 같아도 다른 객체이기 때문에 다른 주소값.
System.out.println(num1.equals(num3)); // true  | equals() 메서드를 사용하면 예상대로 출력된다.

System.out.println(num1 < num2);       // true  | 그 외 비교연산은 잘 출력된다.

 

 


 

참고문헌

https://inpa.tistory.com/entry/JAVA-%E2%98%95-wrapper-class-Boxing-UnBoxing#%EB%9E%98%ED%8D%BC_%ED%81%B4%EB%9E%98%EC%8A%A4_%EB%8F%99%EB%93%B1_%EB%B9%84%EA%B5%90

https://www.geeksforgeeks.org/wrapper-classes-java/

 

'JAVA' 카테고리의 다른 글

[JAVA] ORM 이란?  (0) 2025.05.31
[JAVA] JDBC 정리  (0) 2025.05.27
[JAVA] 스레드(Thread) 정리  (0) 2025.03.01
[JAVA] 컬렉션(Collection) 정리 / Map  (0) 2025.02.27
[JAVA] 컬렉션(Collection) 정리 / List, Set, Queue  (0) 2025.02.24