[Java] Wrapper 클래스, 박싱과 언박싱

Wrapper 클래스란?

기본 자료형(int, double, long, boolean, …)의 데이터를 인스턴스(객체)로 만들기 위해 사용하는 클래스이다.

기본 자료형의 값을 굳이 wrapper 클래스로 포장하는 이유는 제너릭, 자료구조, 매개변수 등 기본 자료형이 아닌 래퍼런스 타입을 필요로 하는 경우가 많고, wrapper 클래스는 메소드를 가지고 있어 다양하게 활용이 가능하기 떄문이다.

그리고 인스턴스를 생성(heap 메모리에 저장) 하여 상속 및 재사용이 가능하다. 또한, 문자열(String)과 기본 자료형 간 형변환 하여 사용이 가능하다.


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


박싱과 언박싱

박싱 : 기본 자료형의 데이터를 wrapper 클래스의 객체로 만드는 과정
언박싱 : wrapper 클래스의 데이터를 기본 자료형으로 얻어내는 과정


값 비교

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {	
	int a=1, b=1;
	Integer aa = new Integer(a);
	Integer bb = new Integer(b);
	
	System.out.println("언박싱 : "+(a==b)); // true
	System.out.println("박싱 : "+(aa==bb)); // false
	System.out.println("박싱 : "+(aa.intValue()==bb.intValue())); // true
}

위에서 알 수 있듯이 박싱된 객체를 비교하게 되면 값은 값임에도 불구하고 false 를 반환하게 된다.

Integer 라는 박싱에는 값 이외에도 식별성이라는 속성이 존재하기 때문이다.


속도비교

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 박싱
public static void main(String[] args) {	
	Long boxingSum = 0L; // 박싱 사용
	long startTime = System.currentTimeMillis();
	
	for(long i=0; i<Integer.MAX_VALUE; i++) {
		boxingSum += 1;
	}
	long endTime = System.currentTimeMillis() - startTime;
	System.out.println("endTime : "+endTime);
}

// 언박싱
public static void main(String[] args) {	
	long nonBoxingSum = 0L; // 언박싱 사용
	long startTime = System.currentTimeMillis();
	
	for(long i=0; i<Integer.MAX_VALUE; i++) {
		nonBoxingSum += 1;
	}
	long endTime = System.currentTimeMillis() - startTime;
	System.out.println("endTime : "+endTime);
}

위 두개의 메소드를 비교하면 10배가 넘는 속도차이를 확인 할 수 있다. (언박싱이 더 빠름)

이와 같은 차이가 나는 이유는 boxingSum += 1; 에 대한 처리를 할 때 auto boxing이 발생해 작은 속도저하가 모여 성능을 저하시켰기 때문이다.

몹시 중요한 부분이다. 작은 속도저하가 모여 결국 성능저하를 일으켰다는 점.

박싱 된 객체를 intValue() 할 때, 값이 null 일 경우 Runtime Exception 인 NPE 가 발생하고, 성능저하가 발생 할 수 있기 때문에 박싱을 사용할때는 주의해서 사용해야 한다.


Entity 에선 뭘 사용해야할까?

Long 을 사용하자.

JPA Entity 에서의 Primary 은 식별을 위한 용도이며, 연산을 위해 사용되지 않는다. 그리고 다른 테이블에 join 할 때 사용되기도 한다.

여기서 알 수 있 듯 join 되는 컬럼에 대해서는 null 이 존재하지 않도록 모델링 되야하지만, 그렇지 않은 상황이 생길 수 도 있다. 그러니 null 이어도 직접 예외 대응이 가능하도록 Long 을 사용하도록 하자.


Tags:

Updated:

Leave a comment