# Wrapper 클래스란?
- 자바는 기본 데이터 타입을 객체로 다루지 않는다.
- 기본 데이터 타입을 객체로 다루기 위해 자바에서는 Wrapper 클래스를 제공한다.
## 기본 데이터 타입과 Wrapper 클래스
| 기본 데이터 타입 | Wrapper 클래스 |
| :--------------- | :------------- |
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
## Wrapper 클래스의 필요성
- 객체로서의 기능 제공 : 기본 데이터 타입은 객체가 아니므로, 객체 지향 프로그래밍의 이점을 활용할 수 없다. Wrapper 클래스를 사용하면 메소드를 호출하거나, 객체 간의 비교, 객체 컬렉션에 저장하는 등의 작업을 할 수 있다
- **프로그램에 따라 기본 타입의 데이터를 객체로 취급해야 하는 경우가 있다. 이런 경우 Wrapper 클래스를 사용한다.**
- null 값을 허용 : 기본 데이터 타입은 null 값을 가질 수 없다. 반면, Wrapper 클래스는 객체이므로 null 값을 할당할 수 있다. 이는 데이터가 없거나 미정인 상황을 표현할 때 유용하다
- 제네릭과 컬렉션 : 자바의 제네릭 시스템은 객체 타입에만 작동한다. 따라서 기본 데이터 타입을 사용해야 할 때, 해당 데이터 타입의 Wrapper 클래스를 사용해야 제네릭과 컬렉션을 사용할 수 있다
## Wrapper 클래스의 생성 및 초기화
Wrapper 클래스 객체는 다음 두 가지 방법으로 생성 및 초기화할 수 있다
- 생성자 사용
```java
Integer intValue = new Integer(100);
Double doubleValue = new Double(55.5);
```
- valueOf 메서드 사용
```java
Integer intValue = Integer.valueOf(100);
Double doubleValue = Double.valueOf(55.5);
```
### 박싱(Boxing)과 언박싱(Unboxing)

- **박싱**: 기본 데이터 타입의 값을 Wrapper 클래스의 객체로 변환하는 과정
- 생성자 사용
```java
Integer intValue = new Integer(100); // 박싱
Double doubleValue = new Double(55.5); // 박싱
```
> 이 방식으로 객체를 생성하는 것은 자바 9부터 deprecated 되었다. 자바 9부터는 `valueOf` 메서드를 사용하여 객체를 생성하는 것을 권장한다.
- valueOf 메서드 사용
```java
Integer intValue = Integer.valueOf(100);
Double doubleValue = Double.valueOf(55.5);
```
- **언박싱**: Wrapper 클래스의 객체를 기본 데이터 타입의 값으로 변환하는 과정
```java
Integer intValue = Integer.valueOf(100);
Double doubleValue = Double.valueOf(55.5);
int i = intValue.intValue(); // 언박싱
double d = doubleValue.doubleValue(); // 언박싱
```
### 오토 박싱과 언박싱
자바 5부터는 오토 박싱(Auto Boxing)과 언박싱(Unboxing)이 도입되었다. 이 기능은 기본 데이터 타입과 Wrapper 클래스 간의 변환을 자동으로 처리한다.
- **오토 박싱**: 기본 데이터 타입을 자동으로 해당 Wrapper 클래스의 객체로 변환한다.
```java
Integer intValue = 100; // 자동으로 Integer 객체로 변환
```
- **언박싱**: Wrapper 클래스의 객체를 자동으로 기본 데이터 타입의 값으로 변환한다.
```java
int i = intValue; // 자동으로 기본 데이터 타입의 값으로 변환
```
## Wrapper 클래스의 메소드
- `intValue()`, `doubleValue()` 등의 메소드를 사용하여 다른 타입의 기본 데이터로 변환할 수 있다.
- `compareTo()`, `equals()` 등의 메소드로 객체 간 비교를 수행할 수 있다.
- `toString()` 메소드로 문자열 표현을 얻을 수 있다.
- `parseXXX()` 메소드로 문자열을 기본 데이터 타입으로 변환할 수 있다.
- `valueOf()` 메소드로 기본 데이터 타입의 값을 Wrapper 클래스의 객체로 변환할 수 있다.
- `MAX_VALUE`, `MIN_VALUE` 등의 상수를 사용하여 Wrapper 클래스가 표현할 수 있는 값의 범위를 알 수 있다.
## 예시
```java
public class WrapperExample {
public static void main(String[] args) {
// 오토 박싱
Integer intValue = 100;
// 오토 언박싱
int i = intValue;
// 메소드 사용
System.out.println("intValue: " + intValue);
System.out.println("double value: " + intValue.doubleValue());
// 비교
Integer anotherIntValue = 100;
System.out.println("두 Integer 객체 비교: " + intValue.equals(anotherIntValue));
// 문자열 변환
String str = intValue.toString();
System.out.println("문자열 변환: " + str);
// 문자열을 기본 타입으로 변환
int num = Integer.parseInt(str);
System.out.println("문자열을 기본 타입으로 변환: " + num);
// MAX_VALUE, MIN_VALUE
System.out.println("Integer가 표현할 수 있는 최대값: " + Integer.MAX_VALUE);
System.out.println("Integer가 표현할 수 있는 최소값: " + Integer.MIN_VALUE);
System.out.println("Short가 표현할 수 있는 최대값: " + Short.MAX_VALUE);
System.out.println("Short가 표현할 수 있는 최소값: " + Short.MIN_VALUE);
// ...
}
}
```
## 주의사항
- Wrapper 클래스의 객체는 변경 불가능한(immutable) 객체이다. 따라서 값을 변경하는 메소드를 제공하지 않는다
- Wrapper 클래스의 객체는 == 연산자로 비교하면 안 된다. == 연산자는 두 객체의 주소 값을 비교하므로, 객체의 내용을 비교하려면 `equals()` 메소드를 사용해야 한다
- Wrapper 클래스의 객체는 null 값을 가질 수 있다. 이는 기본 데이터 타입의 변수가 null 값을 가질 수 없는 것과 차이가 있다
- 만약 언박싱 할 때 null 값을 가진 객체라면 `NullPointerException`이 발생한다
- Wrapper 클래스는 상대적으로 무거운 객체이므로, 가능하다면 기본 데이터 타입을 사용하는 것이 좋다