Published 2022. 1. 30. 02:12

 포장 객체

- 기본 타입의 값을 내부에 두고 포장.

- 포장하고 있는 기본 타입 값은 외부에서 변경할 수 없다.

- byte, char, short, int, long, float, double, boolean 기본 타입 값을 갖는 객체이다.

 

Boxing과 Unboxing

- Boxing(박싱) : 기본 타입의 값을 포장 객체로 만드는 과정

- Unboxing(언박싱) : 포장 객체에서 기본 타입의 값을 얻어내는 과정


Boxing(박싱)

ex) Byte obj = new Byte(10);     

    Byte obj = new Byte("10");


생성자의 매개 값으로 기본 타입의 값을 주느냐 아니면 문자열을 주느냐에 따라 차이가 발생한다.
기본 타입의 경우는 값을 박싱한 Wrapper 객체가 만들어진다.

생성자의 매개 값으로 문자열을 주게 될 경우 이 문자열을 해당 기본 타입으로 변환하고 박싱한 후 Wrapper 객체를 만들어준다.

 

또 다른 방법으로는??

생성자를 이용하지 않고 각 포장 클래스마다 가진 정적 valueOf() 메소드 활용한다.

Interger obj = Integer.valueOf(1000);
Interger obj = Integer.valueOf("1000");


valueOf 메소드는 해당 포장 클래스 타입의 wrapper 객체를 생성하는데 이 경우 Integer니까 int타입으로 변환 후 그것을 Integer객체 안에 넣어서 참조를 리턴해준다. 다른 포장 클래스도 이와 같은 형태로 wrapper 객체를 만들 수 있다.

 

Unboxing(언박싱)

'기본타입이름 + Value()' 메소드 호출하여 언박싱

ex) byte : num = obj.byteValue();

 

 자동박싱과 언박싱

 포장 클래스 타입에 기본값이 대입될 경우 자동 박싱 발생

 

 Integer obj = 100; // 자동박싱

 

자바 문법에서는 기본타입의 값은 클래스타입에 대입 불가능하다. 근데 위와 같이 가능한 이유는 100이라는 기본타입의 값은 Integer객체에 자동으로 포장되어 즉, Boxing(박싱)되어 실제 대입되는것은 포장객체의 번지가 대입되는것이다. 이것을 자동박싱이라고 한다.

 

- 기본 타입에 포장 객체가 대입되는 경우 및 연산자에서 자동 언박싱 발생

Integer obj = new Integer(200);
int value1 = obj;  //자동언박싱
int value2  = obj + 100; //자동언박싱

 이 코드를 해석하자면 obj래퍼객체 안에 있는 기본타입의 값을 끄집어내서 그것과 100을 산술연산을 해서 결과를 value2에 저장하라는 뜻이다.

 

문자열을 기본 타입 값으로 변환

- 포장 클래스로 문자열을 기본 타입 값으로 변환

- 'parse + 기본 타입 이름' 정적 메소드

 

byte  num = Byte.parseByte("10"); // 주어진 매개값 10을 즉 문자열 10을 Byte타입으로 변환해서 리턴을 한다.

 

 


 포장값 비교

- 포장 객체는 내부 값 비교하기 위해 == 및 != 연산자 사용하지 않는 것이 좋다.

(포장객체 타입 자체는 기본객체가 아니라 객체임, == !=는 객체의 번지를 비교하는 것이다 객체 내부의 값을 비교할때 쓰지말라는 뜻이다.)


코드를 보고 넘어가자.

public class ValueCompareExample {

	public static void main(String[] args) {
		
        //첫번째 코드
		Integer obj1 = 300; 
		Integer obj2 = 300; //자동박싱
       
		
		System.out.println("==결과: " + (obj1 == obj2));
		 //결과 = false
        
        //두번째 코드
		Integer obj3 = 10; 
		Integer obj4 = 10;
		System.out.println("==결과: " + (obj3 == obj4));
                //결과 = true
	}

}

첫번째 코드 결과값은 false가 나온다. 그 이유는 obj1은 300이 아니기 때문이다. obj1은 300을 포장하고 있는 포장객체이다. obj2도 마찬가지입니다. 따라서 객체의 == 의 의미는 번지 비교이다.  obj1이 참조하고 있는 300의 래퍼객체의 번지와 obj2가 참조하고 있는 래퍼객체는 다른것이다. 그래서 주소가 다르므로 false가 나온다

 

우리를 헷갈리게 하는 것은?? 

박싱된 값이 표에 나와 있는 범위의 값이 아닌 경우 언박싱한 값 얻어 비교해야 한다.

타입 값의범위
boolean true.false
char \u0000 ~ \u007f
byte, short, int -128 ~ 127

말이 너무 어렵다..

하지만!!!

 

쉽게 얘기해서 이 범위를 포장하고 있는 포장객체는 이 범위 값을 비교를 할때 == != 연산자를 쓸 수 있다는 소리다!

예를 들면

     Integer obj3 = 10; //자동박싱이 됌
     Integer obj4 = 10;

두번째 코드를 실행하게 되면 결과 값이 true가 나온다.

 

일관성이 없다?
첫번째 코드는 서로 다른 객체를 참조하니까 당연히 false가 나오는건데 두번째도 다른 객체를 참조하는데 왜 true가 나올까?? 과연 obj3과 obj4가 같은 객체를 참조하는 걸까??


정답은??!

자바는 범위의 값을 많이 사용하기 때문에 범위의 값을 박싱할때 이전의  박싱된 어떤 객체가 있다하면 그 객체를 재사용해서 사용한다. byte나 shrot나 int가 -128 ~ 127 범위에서 박싱되었다면 박싱된 객체를 공유해서 사용합니다.

 

첫번째 코드를 보게 되면 300이라는 값은 범위(-128 - 127)안에 속하지 않으므로 따로따로 박싱이 되어서 다른 객체가 만들어 지는것이고

두번째 코드를 보면 10이 범위에 속하기 때문에 10을 박싱한 객체를 하나만 만들어서 obj3 과 obj4가 똑같이 참조할 수 있도록 해주는 것이다. 그래서 두번째 코드는 true 첫번째 코드는 다르므로 false가 나오는 것이다.

 

'IT > Java' 카테고리의 다른 글

[Java] 예외 처리  (0) 2022.01.26
[Java] 예외클래스  (0) 2022.01.26
[Java] 상속, 오버라이딩, final 키워드  (0) 2022.01.21
[Java] 필드선언, 필드 사용  (0) 2022.01.17
[Java] 객체 지향 프로그래밍  (0) 2022.01.17
복사했습니다!