11.12 Wrapper(포장) 클래스
자바는 기본 타입(byte, char, short, int, long, float, double, boolean) 의 값을 갖는 객체를 생성할 수 있다. 이런 객체를 포장(Wrapper) 객체라고 하는데, 그 이유는 기본 타입의 값을 내부에 두고 포장하기 때문이다. 포장 객체의 특징은 포장하고 있는 기본 타입 값은 외부에서 변경할 수 없다. 만약 내부의 값을 변경하고 싶다면 새로운 포장 객체를 만들어야 한다.
포장 클래스는 java.lang 패키지에 포함되어 있는데, 다음과 같이 기본 타입에 대응되는 클래스들이 있다. char 타입과 int 타입이 각각 Character 와 Integer로 변경되고, 기본 타압의 첫 문자를 대문자로 바꾼 이름을 가지고 있다.
기본타입 | 포장 클래스 |
byte | Byte |
char | Character |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
11.12.1 박싱(Boxing) 과 언박싱(Unboxing)
기본 타입의 값을 포장 객체로 만드는 과정을 박싱(Boxing) 이라고 하고, 반대로 포장 객체에서 기본 타입의 값을 얻어내는 과정을 언박싱(Unboxing)이라고 한다. 다음은 8개의 기본 타입의 값을 박싱하는 방법을 보여주고 있다. 간단하게 포장 클래스의 생성자 매개값으로 기본 타입의 값 또는 문자열을 넘겨주면 된다.
기본 타입의 값을 줄 경우 | 문자열을 줄 경우 |
Byte obj =new Byte(10); | Byte obj =new Byte("10"); |
Character obj =new Character('가'); | 없음 |
Short obj =new Short(100); | Short obj =new Short("100"); |
Integer obj=new Integer(1000); | Integer obj=new Integer("1000"); |
Long obj=new Long(10000); | Long obj=new Long("10000"); |
Float obj=new Float(2.5F); | Float obj =new Flaot("2.5F"); |
Double obj=new Double(3.5); | Double obje =new Double("3.5"); |
Boolean obj=new Boolean(true); | Boolean obj =new Boolean("true"); |
생성자를 이용하지 않아도 다음과 같이 각 포장 클래스마다 가지고 있는 정적 valueOf() 메소드를 사용할 수도 있다.
Integer obj =Integer.valueOf(1000);
Integer obj =Integer.valueOf("1000");
이렇게 박싱된 포장 객체에서 다시 기본 타입의 값을 얻어 내기 위해서는 (언박싱하기 위해서는 )각 포장 클래스마다 가지고 있는 "기본타입명+ value()" 메소드를 호출하면 된다.
기본 타입의 값을 이용 |
byte num =obj.byteValue(); |
char ch =obj.charValue(); |
short num =obj.shortValue(); |
int num =obj.intValue(); |
long num =obj.longValue(); |
float num =obj.floatValue(); |
double num =obj.doubleValue(); |
boolean bool =obj.booleanValue(); |
public class BoxingUnBoxingExample {
public static void main(String[] args) {
//Boxing
Integer obj1 =new Integer(100);
Integer obj2 =new Integer("200");
Integer obj3 =Integer.valueOf("300");
//Unboxing
int value1 =obj1.intValue();
int value2 =obj2.intValue();
int value3 =obj3.intValue();
System.out.println(value1);
System.out.println(value2);
System.out.println(value3);
}
}
100
200
300
11.12.2 자동 박싱과 언박싱
기본 타입 값을 직접 박싱, 언박싱하지 않아도 자동적으로 박싱과 언박싱이 일어나는 경우가 있다. 자동 박싱은 포장 클래스 타입에 기본값이 대입될
경우에 발생한다. 예를 들어 int 타입의 값을 Integer 클래스 변수에 대입하면 자동 박싱이 일어나 힙 영역에 Integer 객체가 생성된다.
Integer obj =100 // 자동 박싱
자동 언박싱은 기본 타입에 포장 객체가 대입될 경우에 발생한다. 예를 들어 Integer 객체를 int 타입 변수에 대입하거나, Integer 객체와 int 타입값을 연산하면 Integer 객체로부터 int 타입의 값이 자동 언박싱되어 연산된다.
Integer obj =new Integer(200);
int value1=obj; //자동 언박싱
int value2 =obj + 100 ; // 자동 언박싱
참고로 15장에서 학습할 컬렉션 객체에 int 값을 저장하면 자동 박싱이 일어나 Integer 객체가 저장된다.
List list =new ArrayList();
list.add(200); //자동 박싱
자공 박싱과 언박싱은 자바 5부터 추가된 기능이기 때문에 자바 4 이전 버번에서는 직접 박싱과 언박싱을 해주어야 한다. 엄격한 코딩 문법을 사용하는 자바 언어에서 다소 예외적인 문법이지만, 자동 박싱과 언박싱은 코드를 간결하게 만들어주는 역할을 한다.
public class AudoBoxingUnBoxingExample {
public static void main(String[] args) {
//자동 Boxing
Integer obj =100;
System.out.println("value :" + obj.intValue());
//대입 시 자동 Unboxing
int value =obj;
System.out.println("value : "+ value);
//연산 시 자동 Unboxing
int result = obj + 100;
System.out.println("result : " + result);
}
}
value :100
value : 100
result : 200
11.12.3 문자열을 기본 타입 값으로 변환
포장 클래스의 주요 용도는 기본 타입의 값을 박싱해서 포장 객체로 만드는 것이지만, 문자열을 기본 타입 값으로 변환할 때에도 많이 사용된다.
대부부의 포장 클래스에는 "parse + 기본타입" 명으로 되어 있는 정적(static) 메소드가 있다. 이 메소드는 문자열을 매개값으로 받아 기본 타입 값으로 변환한다.
기본 타입의 값을 이용 |
byte num =Byte.parseByte("10"); |
short num =Short.parseShort("100"); |
int num =Integer.parseInt("1000"); |
long num =Long.parseLong("10000"); |
float num =Float.parseFloat("2.5F"); |
double num =Double.parseDouble("3.5"); |
boolean bool =Boolean.parseBoolean("true"); |
public class StringToPrimitiveValueExample {
public static void main(String[] args) {
int value1 =Integer.parseInt("10");
double value2 =Double.parseDouble("3.14");
boolean value3 =Boolean.parseBoolean("ture");
System.out.println("value1: " + value1);
System.out.println("value2: " + value2);
System.out.println("value3: " + value3);
}
}
11.12.4 포장 값 비교
포장 객체는 내부의 값을 비교하기 위해 == 와 != 연산자를 사용할 수 없다. 이 연산자는 내부의 값을 비교하는 것이 아니라 포장 객체의 참조를 비교하기 때문이다. 예를 들어 다음 두 Integer 객체는 300 이라는 동일한 값을 갖고 있지만 == 연산의 결과는 false 가 나온다.
Integer obj1 =300;
Integer obj2 =300;
System.out.println(obj1==obj2);
내부의 값만 비교하려면 언박싱한 값을 얻어 비교해야 한다. 그러나 자바 언어 명세에 보면 다음과 같은 규칙이 있다. 박싱된 값이 다음 표에 나와 있는 값이라면 == 와 != 연산자로 내부의 값을 바로 비교할 수 있다. 그 이외의 경우에는 박싱된 값을 ==와 != 연산자로 비교할 수 없다.
타입 | 값의 범위 |
boolean | true, flase |
char | \u0000 ~ \u00f |
byte, short,int | -128 ~127 |
포장 객체에 정확히 어떤 값이 저장될지 모르는 상황이라면 ==와 != 연산자는 사용하지 않는 것이 좋다. 직접 내부 값을 언박싱해서 비교하거나, equals() 메소드로 내부 값을 비교하는 것이 좋다.
포장 클래스의 equals() 메소드는 내부의 값을 비교하도록 오버라이딩되어 있다.
public class ValueCompareExample2 {
public static void main(String[] args) {
System.out.println("[-128~127 초과값일 경우]");
Integer obj1 = 300;
Integer obj2 =300;
System.out.println("==결과 : " + (obj1 ==obj2));
System.out.println("언박싱후 == 결과 : " + (obj1.intValue() == obj2.intValue()));
System.out.println("equals() 결과 :" + obj1.equals(obj2));
System.out.println();
System.out.println("[-128~127 범위값일 경우");
Integer obj3 =10;
Integer obj4 = 10;
System.out.println("==결과 : " + (obj3==obj4));
System.out.println("언박싱후 == 결과 : " + (obj3.intValue() == obj4.intValue()));
System.out.println("equals() 결과 :" + obj3.equals(obj4));
}
}
[-128~127 초과값일 경우]
==결과 : false
언박싱후 == 결과 : true
equals() 결과 :true
[-128~127 범위값일 경우
==결과 : true
언박싱후 == 결과 : true
equals() 결과 :true
댓글 ( 4)
댓글 남기기