Wrapper 클래스 (포장 클래스)

자바에는 래퍼클래스 라는것이 있습니다.
래퍼 클래스는 말그대로 포장 클래스입니다.
그럼 무엇을 포장하느냐? 그것은 바로 기본 자료형 데이터를 포장합니다.

자바는 완벽한 객체지향 언어이고 모든 것이 객체로 이루어져 있다고 말하지만 객체가 아닌것들이 존재합니다.
그것은 바로 기본 자료형입니다. 
8개의 기본 자료형인 byte, short, int, long, char, float, double, boolean 은 객체가 아닙니다.
이들이 객체가 아닌 이유는 가장 빈번한 연산을 하는 데이터들이기 때문에 높은 성능을 이끌어내기 위해서였을 것입니다.
아무래도 객체는 기본 자료형 데이터보다 덩치가 크고 그렇게 되면 연산시 더 많은 자원을 요구하기 때문입니다.

그러나 이러한 기본자료형이 객체가 아니면 불편한 경우가 있습니다.
가장 대표적인 예가 컬렉션을 사용하거나 다형성을 이용할 때 또는 제네릭을 사용할 때 입니다.
1
2
3
4
5
6
7
8
9
List list = new ArrayList();
 
int a = 3;
double b = 2.5;
char c = 'a';
 
list.add(a);
list.add(b);
list.add(c);
cs

  

위의 코드를 java 1.4 버전에서 실행하게 되면 다음과 같은 예외를 만날 수 있습니다.
(참고! 제네릭은 1.5버전 부터 지원되고 List는 기본적으로 Object를 담을 수 있게 만들어져 있습니다.)

그 이유는 Object는 상속 계층도의 최상위 클래스지만 기본자료형은 객체가 아니기 때문에 다형성이 적용되지 않아서 담을 수 없기 때문입니다.

 

1
2
3
4
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
    The method add(int, Object) in the type List is not applicable for the arguments (int)
    The method add(Object) in the type List is not applicable for the arguments (double)
    The method add(Object) in the type List is not applicable for the arguments (char)
cs

 


그래서 필요한 것이 래퍼 클래스입니다.
래퍼 클래스들은 내부적으로 다음과 같이 구성 되어 있습니다.

 

1
2
3
4
5
public final class Integer extends Number implements Comparable<Integer> {
     ...생략...
     private final int value;
     ...생략...
}
cs

 

모양이 마치 기본자료형을 감싼 것처럼 보입니다.
래퍼 클래스의 상속 계층도는 다음과 같습니다.


Number 클래스
Number 클래스의 경우는 숫자와 관련된 래퍼클래스들의 추상클래스입니다.

BingInteger와 BingDecimal
BigInteger 클래스와 BigDeciaml 클래스는 생소할 수도 있는데 BigInteger의 경우 Long을 넘어선 범위의 정수를 표현할 수 있고, BigDecimal의 경우 Double로 표현할 수 있는 범위를 넘어선 실수를 표현할 수 있는 유용한 클래스 입니다.

처음에 예외가 났던 코드는 래퍼클래스를 이용하여 다음과 같이 고칠 수 있습니다.

 

1
2
3
4
5
6
7
8
9
List list = new ArrayList();
 
Integer a = new Integer(3);
Double b = new Double(2.5);
Character c = new Character('a');
 
list.add(a);
list.add(b);
list.add(c);
cs

이렇게 되면 기본자료형 또한 객체지향 언어인 자바의 색깔에 맞게 속성과 메서드를 갖는 객체로서 포장 되어져 이용할 수 있게 됩니다.
또한 숫자형 래퍼클래스의 경우 생성자 매개변수로 new Integer("3"); 과 같이 문자열을 이용할 수 있습니다.

주의할 점으로는 new Integer("3.5");  와 같이 숫자가 아닌 문자열을 생성자 매개변수로 사용하게 되면 NumberFormatException이 발생합니다.
마찬가지로 new Integer(3.0); 과 같이 자료형을 맞추어 주지 않으면 예외가 발생합니다.

 

1
2
3
Integer a = new Integer("3"); //3
Integer b = new Integer(3.5); //The constructor Integer(double) is undefined
Integer c = new Integer("3.5"); //NumberFormatException
cs

 

 


 

Wrapper 클래스의 연산
래퍼 클래스를 생성하는 법을 알아 보았는데 이번에는 래퍼클래스의 연산에 대해 알아보도록 하겠습니다.
래퍼 클래스들은 기본적으로 다음과 같이 기본 자료형으로 변환하여 연산할 수 있습니다.

 

1
2
3
4
5
6
7
8
9
Integer a = new Integer(3);
Double b = new Double(2.5);
 
int intValue = a.intValue();
double doubleValue = b.doubleValue();
 
//단 Character의 경우 charValue() 임에 주의!
 
System.out.println(intValue + doubleValue); //5.5
cs

비교연산
비교 연산의 경우 바로 아래서 배우겠지만 컴파일러가 오토박싱과 언박싱을 해주기 때문에 헷갈릴 수 있습니다.
기본자료형와 래퍼간의 연산에서 == 연산과 equals 연산 모두 성립합니다.

 

1
2
3
4
5
Integer a = new Integer(3);
int i = 3;
 
System.out.println(a == i); //true
System.out.println(a.equals(i)); //true
cs

그러나 래퍼와 래퍼 사이에서 연산은 ==은 성립하지 않고 equals만 성립하게 됩니다.
그러나 <, > 같이 크기가 다른 경우의 비교는 성립합니다.
헷갈리니 주의해야 합니다.

1
2
3
4
5
Integer a = new Integer(35);
Integer i = new Integer(35);
 
System.out.println(a == i); //false 참조값 연산을 함
System.out.println(a.equals(i)); //true 값으로 연산
cs

 

오토박싱과(Boxing) 오토언박싱(Unboxing)

그런데 또 한가지 불편한 점이 생겼습니다.
기본 자료형을 사용할때는 13 + 2 와 같이 간단하게 리터럴을 가지고 연산을 했지만 래퍼클래스를 이용하게 되면 참조형 끼리의 연산이 불가능 하기 때문에 기본 자료형으로 변환하여 연산하게 된 것입니다.

그래서 자바 1.5부터는 오토박싱과 오토 언박싱 이라는 개념이 추가 되었습니다.
먼저 오토박싱의 경우 명시적으로 기본자료형을 래퍼클래스로 감싸주지 않아도 박싱(포장 = wrapping) 해 주는 것입니다.
1
2
Integer a = 3// 내부적으로는 Integer a = new Integer(3); 으로 변환하여 동작
Object o = 3//마찬가지로 Object o = new Integer(3); 으로 동작하여 다형성 적용
cs

 


오토언박싱의 경우 그 반대의 경우입니다.
명시적으로 기본자료형으로 변환하지 않아도 포장을 풀어줍니다.
1
2
Integer a = new Integer(3);
int i = a; //내부적으로 int i = a.intValue(); 로 바뀌어 동작
cs


래퍼 클래스의 문자열 변환
래퍼클래스를 이용하여 문자열을 기본 자료형으로 변환시킬 수 있습니다.
1
2
3
4
5
6
7
8
9
10
String str = "100";
String str2 = "3.5";
 
byte b = Byte.parseByte(str);
short s = Short.parseShort(str);
int i = Integer.parseInt(str);
long l = Long.parseLong(str);
float f = Float.parseFloat(str2);
double d = Double.parseDouble(str2);
Boolean bool = Boolean.parseBoolean("true");
cs


또는 문자열을 래퍼클래스로 변환 시킬 수 있습니다.
parse 메서드와 valueOf 메서드의 차이점은 래퍼클래스로 변환하냐 기본자료형으로 변환하냐의 차이일 뿐 오토박싱 언박싱이 있는 이상 내부 동작 말고는 거의 차이가 없습니다.
1
2
3
4
5
6
7
8
9
10
String str = "100";
String str2 = "3.5";
 
Byte b = Byte.valueOf(str);
Short s = Short.valueOf(str);
Integer i = Integer.valueOf(str);
Long l = Long.valueOf(str);
Float f = Float.valueOf(str2);
Double d = Double.valueOf(str2);
Boolean bool = Boolean.valueOf("true");
cs

 

 

블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

,