게으른 개발자의 끄적거림

Java Int형과 Integer 차이 완벽 정리

끄적잉 2024. 11. 6. 19:08

Java Int형과 Integer 차이 완벽 정리

 

Java에서 `int`와 `Integer`는 모두 정수를 나타내는 자료형이지만, 근본적인 차이점과 사용 방법에서 차이가 큽니다. `int`는 Java의 기본 자료형(primitive type)으로, `Integer`는 자바의 객체(Object)를 기반으로 하는 래퍼 클래스(wrapper class)입니다. 이 두 가지는 비슷해 보이지만, 메모리 사용, 성능, null 처리, 박싱과 언박싱(Boxing and Unboxing) 등에서 다양한 차이를 보입니다. 이 글에서는 `int`와 `Integer`의 차이점, 장단점, 사용 사례 등을 자세하게 설명하겠습니다.


## 1. 기본 개념

### int - 기본 자료형(Primitive Type)
`int`는 자바의 기본 자료형으로, 32비트 크기의 정수를 저장할 수 있습니다. 기본 자료형이기 때문에 별도의 메모리 할당이나 객체 생성 과정이 필요하지 않으며, 단순히 값을 저장하고 연산하는 용도로 빠르게 사용할 수 있습니다.

**특징**:
- 32비트 크기의 메모리 공간을 차지하며, 2^31 ~ -2^31-1 사이의 정수 값을 표현할 수 있습니다.
- 객체가 아니기 때문에 메모리 효율이 높고, 성능이 빠릅니다.
- null 값을 가질 수 없습니다. 기본적으로 메모리에 값을 바로 저장하기 때문에 객체처럼 null로 초기화가 불가능합니다.

### Integer - 래퍼 클래스(Wrapper Class)
`Integer`는 `int`를 객체로 다루기 위해 제공되는 래퍼 클래스입니다. 기본 자료형인 `int`를 감싸고 객체로 변환해 다양한 추가 기능을 제공합니다. 특히, `Integer`는 `int` 값과 관련된 유틸리티 메서드를 제공하여 숫자 변환, 문자열 변환, 비교, 상수 값 제공 등의 다양한 작업을 가능하게 합니다.

**특징**:
- 객체 타입으로, null을 가질 수 있습니다.
- 추가적인 메서드와 상수를 통해 기본 자료형보다 더 많은 기능을 제공합니다.
- 메모리와 성능 측면에서는 `int`에 비해 더 비효율적입니다. 

 


## 2. 메모리 사용 및 성능 차이

### int
`int`는 단순히 4바이트(32비트)의 메모리를 사용하며, 변수에 값을 직접 저장합니다. 기본 자료형으로 처리되기 때문에 할당이나 참조 과정이 없이 빠르게 접근할 수 있습니다. 따라서 메모리와 성능에서 높은 효율성을 보입니다.

### Integer
`Integer`는 객체이므로, 객체 생성 시 추가 메모리가 필요합니다. 객체를 생성할 때 메모리에는 객체 자체의 정보 외에도 참조가 추가됩니다. `Integer`는 객체이기 때문에 Heap 메모리에 저장되고, 참조(reference)를 통해 접근하기 때문에 `int`에 비해 성능이 떨어질 수 있습니다.

또한, `Integer`는 불변 객체(Immutable)로 한 번 생성된 객체는 수정할 수 없고, 새로운 값을 할당할 때마다 새로운 객체를 생성해야 합니다. 이 과정이 자주 반복될 경우 성능에 부정적인 영향을 미칠 수 있습니다.

 


## 3. 박싱(Boxing)과 언박싱(Unboxing)

박싱과 언박싱은 기본 자료형과 객체 타입 간의 변환을 의미합니다.

### 박싱(Boxing)
박싱은 기본 자료형을 해당하는 래퍼 클래스의 객체로 변환하는 과정입니다. 예를 들어, `int` 값을 `Integer` 객체로 변환하는 것이 박싱입니다.

```java
int num = 10;
Integer integerNum = Integer.valueOf(num); // 박싱
```

### 언박싱(Unboxing)
언박싱은 래퍼 클래스 객체를 기본 자료형으로 변환하는 과정입니다. 즉, `Integer` 객체에서 `int` 값을 추출하는 것이 언박싱입니다.

```java
Integer integerNum = Integer.valueOf(10);
int num = integerNum.intValue(); // 언박싱
```

Java 5부터는 오토박싱(Auto-Boxing)과 오토언박싱(Auto-Unboxing)을 지원하여, 개발자가 명시적으로 변환 메서드를 호출하지 않고도 자동으로 변환이 가능합니다.

```java
Integer integerNum = 10; // 오토박싱
int num = integerNum; // 오토언박싱
```

### 박싱과 언박싱의 성능 이슈
박싱과 언박싱은 성능에 영향을 줄 수 있습니다. 예를 들어, 기본 자료형을 반복적으로 객체로 변환하거나, 그 반대의 작업을 반복할 경우 메모리 사용량과 성능에 부담이 될 수 있습니다.

 


## 4. Null 처리

### int
`int`는 기본 자료형으로, null 값을 가질 수 없습니다. `int` 변수를 선언하면 반드시 초기값(0)이나 특정 값을 할당해야 합니다.

```java
int number = 0; // null이 아닌 초기값이 필요함
```

### Integer
`Integer`는 객체이므로 null 값을 가질 수 있습니다. 이로 인해 `Integer`는 데이터베이스에서 값이 없음을 나타내거나, 메서드의 반환 값으로 값이 없음을 나타내는 데 유용합니다. 하지만 null 값을 갖는 `Integer`를 사용할 때는 `NullPointerException`에 주의해야 합니다.

```java
Integer number = null; // null 값 허용
```

 


## 5. 비교 연산

### int의 비교
기본 자료형 `int`는 `==` 연산자를 통해 값을 바로 비교할 수 있습니다. 이 연산자는 메모리 주소가 아닌 실제 값을 비교하므로 빠르고 직관적입니다.

```java
int a = 10;
int b = 10;
System.out.println(a == b); // true, 값 비교
```

### Integer의 비교
`Integer`는 객체이므로, 두 `Integer` 객체를 비교할 때 `==` 연산자는 객체의 주소를 비교합니다. 따라서 값 비교를 위해서는 `equals()` 메서드를 사용하는 것이 권장됩니다.

```java
Integer a = 10;
Integer b = 10;
System.out.println(a == b); // true 또는 false
System.out.println(a.equals(b)); // true, 값 비교
```

### 주의할 점
`Integer`는 -128에서 127 사이의 값은 캐시로 저장하여 동일한 객체를 반환합니다. 즉, 이 범위 내에서는 동일한 값을 가진 `Integer` 객체에 대해 `==` 연산이 참일 수 있지만, 범위를 벗어난 값은 서로 다른 객체로 처리되기 때문에 `==` 연산 시 결과가 다를 수 있습니다.

```java
Integer x = 100;
Integer y = 100;
System.out.println(x == y); // true, 캐싱된 객체

Integer x2 = 200;
Integer y2 = 200;
System.out.println(x2 == y2); // false, 다른 객체
```

 


## 6. 사용 사례 및 권장 사항

### int 사용 시기
- 성능이 중요한 경우 `int`를 사용하는 것이 좋습니다. 메모리 사용량이 적고, 연산이 빠르기 때문에 큰 데이터 처리나 반복적인 계산이 필요한 경우 유리합니다.
- null 값을 처리할 필요가 없을 때 `int`를 사용합니다.

### Integer 사용 시기
- 컬렉션과 같은 객체를 사용하는 경우 `Integer`를 사용해야 합니다. 예를 들어, `ArrayList<Integer>`와 같은 제네릭 컬렉션에는 기본 자료형을 사용할 수 없으므로, 래퍼 클래스인 `Integer`를 사용해야 합니다.
- null 값을 사용해야 하거나, 데이터베이스에서 값이 없음을 나타내기 위해 null을 처리할 필요가 있을 때 `Integer`를 사용합니다.
  
## 결론

`int`와 `Integer`는 비슷한 용도로 사용될 수 있지만, 차이점이 분명하여 상황에 따라 적절한 타입을 선택하는 것이 중요합니다. `int`는 메모리와 성능 효율이 뛰어나며, 단순 계산이나 반복 작업에서 자주 사용됩니다. 반면, `Integer`는 객체 타입으로 null 처리가 가능하고, 컬렉션과 같은 객체 기반 구조에서 사용됩니다.