1️⃣ 박싱된 기본 타입이란?자바의 데이터 타입 2가지기본타입과 박싱된 참조타입의 차이점은?2️⃣ 기본 타입 vs 박싱된 기본 타입주의사항1 - 박싱된 기본 타입의 == 연산주의사항2 - 박싱된 기본 타입과 기본 타입의 연산주의사항3 - 박싱된 기본 타입과 기본 타입의 혼합반드시 박싱된 기본 타입을 사용해야하는 경우🧑🏻⚖️ 결론
1️⃣ 박싱된 기본 타입이란?
Integer
,Long
,Double
등 기본 타입에 대응하는 참조타입을 박싱된 기본타입이라고 한다.
자바의 데이터 타입 2가지
- 기본타입 :
int
,long
,float
,double
등등등
- 참조타입 :
String
,Integer
,List
등등등
- 기본타입은 모두 대응되는 참조타입이 있으며, 이를 박싱된 기본 타입이라고 부른다.
- 개발을 하다보면 오토박싱, 오토언박싱 덕분에 두 타입을 구분하지 않고 사용하지만 둘의 차이는 알고 있어야함
기본타입과 박싱된 참조타입의 차이점은?
- 기본타입은 값만 가질 수 있다. 반면 박싱 타입은 값 자체와는 구별되는 식별성을 갖게된다.
- 기본타입은 완전한 함수적 값이지만, 박싱 타입은 하나의 함수적이지 않은 값,
null
취급이 가능하다.
- 기본타입은 박싱 타입보다 시간 효율성과 공간 효율성이 높다.
2️⃣ 기본 타입 vs 박싱된 기본 타입
- 기본 타입은 값만 가지고 있지만 박싱된 기본 타입은 값과 식별성을 가진다.
final int num1 = 100; final int num2 = 100; sout(num1==num2); // TRUE final Integer num3 = 100; final Integer num4 = 100; sout(num3==num4) // TRUE sout(num3.equals(num4) // TRUE final Integer num5 = new Integer(100); final Integer num6 = new Integer(100); sout(num5==num6); // FALSE sout(num5.equals(num6); // TRUE
용훈님의 질문
- 자바는 실행 시 Integer같은 경우는 리터럴로 값을 할당해줄 때
Integer.valueOf()
를 통해서 값이 저장되게 됩니다. Integer.valueOf()
는 자주 사용하는 숫자 -128~127까지는 미리 캐시에 등록되어 있는 것을 사용하게 됩니다. 따라서 -128 ~127 까지의 == 비교는 같다는 결과를 얻을 수 있어요 🙂



- 기본 타입의 값은 항상 유효하지만 박싱된 기본 타입은
null
을 가질 수 있다.
int num = null // 요것은 안되겠쥬? Integer num = null // 요것은 가능하겠쥬?
- 기본 타입이 박싱된 기본 타입보다 시간과 메모리 측면에서 효율적이다.
세가지 차이점 때문에 주의하지 않으면 문제나 성능 이슈가 생길 수 있음 !
주의사항1 - 박싱된 기본 타입의 == 연산
- 박싱된 기본 타입의
==
연산은 식별성 검사를 하게된다. - 아래의 코드는 제대로 동작하는 것처럼 보이지만 문제가 존재한다. 그것은
Integer
를new
예약어로 같은 값을 넣어서 사용하게 된다면value1==value2
는false
로 나오게 된다. - 이 부분은
String
을new
키워드로 생성하지 않고 리터럴로 생성하는 이유와 같으며 이러한 부분때문에 박싱된 타입은 ==으로 비교하는게 아니라 eqauls로 비교해야 한다.
Comparator<Integer> natureOrder = (value1, value2) -> (value1 < value2) ? -1 : (value1 == value2 ? 0 : 1); natureOrer.compare(new Integer(40), new Integer(40)); // 결과는 1이나온다. // 굳이 해결하자면 ? // 아래처럼 오토언박싱을 사용하면 되긴 하지만 굳이 라는 생각이 든다. Comparator<Integer> natureOrder = (value1, value2) -> { int num1 = value1; int num2 = value2; (num1 < num2) ? -1 : (num1 == num2 ? 0 : 1); }
주의사항2 - 박싱된 기본 타입과 기본 타입의 연산
- 박싱된 기본 타입과 기본 타입의 연산에서는 대부분 박싱된 기본 타입을 오토 언박싱 한다.
- 이때, 박싱된 기본 타입이
null
이면NullPointerException
이 발생한다.
public class Unbelievable { static Integer i; public static void main(String[] args) { if (i == 42) System.out.println("믿을 수 없군!"); } }
주의사항3 - 박싱된 기본 타입과 기본 타입의 혼합
- 기본타입을 오토박싱으로 바꾸거나 박싱된 타입을 다시 기본타입으로 변경하는 작업은 불필요한 객체가 생성되며 이런 작업이 반복된다면 성능저하가 일어날 수 있다.
public static void main(String[] args) { Long sum = 0L; for(long i = 0; i <= Integer.MAX_VALUE; i++) { sum += i; // 오토박싱 } System.out.println(sum); }
용훈님의 질문

반드시 박싱된 기본 타입을 사용해야하는 경우
- 컬렉션의 원소, 키, 값으로 사용할 경우
- 이 부분은 컬렉션을 사용할 때 어쩔 수 없이 기본타입을 사용하지 못하기 때문에 사용해야합니다.
- 매개변수화 타입이나 매개변수화 메서드의 타입 매개변수(제네릭)
- 제네릭에서도 기본타입을 지원하지 않기 때문
- 리플렉션을 통해 메서드를 호출할 경우
🧑🏻⚖️ 결론
- 기본 타입과 박싱된 기본 타입 중 하나를 선택해야 한다면 가능하면 기본 타입을 사용하자.
- 박싱된 기본 타입을 == 연산자로 비교하면 식별성 비교가 이루어진다.
- 박싱된 기본 타입은 equals를 사용하자.
- 박싱된 기본 타입과 기본 타입을 혼용하면 언박싱이 일어나며, 그 과정에서 NPE가 발생할 수 있다.
- 기본 타입을 박싱, 언박싱하는 작업은 필요없는 객체를 생성하는 부작용을 만들고 성능 이슈를 만들 수 있다.