본문 바로가기

Java/Java

[Java] Wrapper Class

Wrapper Class


Wrapper Class는 Object를 구현하는 클래스다.

즉, Wrapper Class는 Object의 메소드를 모두 쓸수있으며,Object를 파라미터로 요구하는 상황에서 유용하게 사용할수있다.

 

WrapperClass의 종류

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

 

WrapperClass 특징

 

1. 메모리 참조

package algorithm;

public class Main {
    
    public static void main(String[] args){
        Integer a = new Integer(999);
        int b = a;
        b = 5;
        Integer c = a;
        System.out.println(a + " " + b + " " + c);
        System.out.println(a == c);
    }
}

위 프로그램을 실행하면,

999, 5, 999

true

가 출력된다.

WrapperClass는 객체이다. 즉, = 연산자를사용할경우, 같은 메모리를 참조하는 레퍼런스 인스턴스가 만들어진다.

즉, Integer c와 Integer a는 같은 메모리를 참조하며, a == c(메모리를 비교할것이므로)의 비교값으로 true를 반환한다.

 

코드에서

        int b = a;

부분을 보자.

WrapperClass a를 일반변수 b에 대입하고있다. 이 경우 WrapperClass는 자동으로 언박싱을한후, 일반변수의 형태로 b에 a의 값을 넣는다.

 

다음 코드를 보자.

package algorithm;

public class Main {
    
    public static void main(String[] args){
        Integer a = new Integer(999);
        int b = a; // 자동 언박싱
        b = 5; 
        Integer c = a;
        System.out.println(a + " " + b + " " + c);
        System.out.println(a == c);
        c = 999; // 자동 박싱
        System.out.println(a + " " + b + " " + c);
        System.out.println(a == c);
        System.out.println(c.equals(a));
    }
}

출력은

999 5 999

true

999 5 999

false

true

이다.

 

마지막에서 바로윗줄에 false가 출력되는걸 볼수있다.

a와 c는 같은 메모리를 참조하는 인스턴스인데, 왜 false가 출력되는것일까? WrapperClass는 값 변경을 허용하지않기때문에, 값 변경이 일어날경우, 새로운 메모리를 할당해 해당영역에 값을 넣는다. 

c = 999; 줄에서 래퍼클래스 c는 숫자 999가 저장된 메모리영역을 힙에 새로 할당해 해당 영역을 참조한다.(이를 자동 박싱이라고한다)

따라서, 

a == c의 경우 다른 메모리주소를 참조하기때문에, false

c.equals(a)의 경우 true가 되는것이다.

또한 이러한 변경방식을 사용함으로써, c의 변경값이 a에게 전달되지않는다.

 


2. 박싱 언박싱

package algorithm;

public class Main {
    
    public static void main(String[] args){
        Integer a = new Integer(999);
        int b = a; // 자동 언박싱
        b = 5; 
        Integer c = a;
        System.out.println(a + " " + b + " " + c);
        System.out.println(a == c);
        c = 999; // 자동 박싱
        System.out.println(a + " " + b + " " + c);
        System.out.println(a == c);
        System.out.println(c.equals(a));
    }
}

위의 코드에서 자동 언박싱과 자동 박싱이라는 주석이 있는곳을 보자.

자동 박싱이 일어나면, 999가 들어있는 메모리영역을 힙에 새로 할당해 c가 해당 영역을 가리키도록 한다. 이러한 원리로 a와 c가 다른 메모리를 참조하게되어서 a == c의 결과가 false가 되는것이다.

자동 언박싱이 일어나면, a에 있던 값이 스택영역할당되어 b는 스택영역에있는 5를 가리킨다.

 

다음은 수동 언박싱의 예시이다.

package algorithm;

public class Main {
    
    public static void main(String[] args){
        Integer a = new Integer(10); // 수동 박싱
        int b = a.intValue(); // 수동 언박싱
    }
}

다른 타입변수의 경우 어떻게 사용할지 대충 감이올것이다

 


3. valueOf, 와 parseInt

래퍼클래스에는 문자열을 변환하는 메소드가 있는데, 해당 메소드의 차이를 알아보자.

우선, valueOf 의 경우, 문자열을 래퍼클래스로 반환한다.

parseInt (parseShort, parseLong...등 동일함)은 문자열을 기본형으로 반환한다.

 

package algorithm;

public class Main {
    
    public static void main(String[] args){
        String b = "123";
        int a1 = Integer.parseInt(b);
        Integer a2 = Integer.valueOf(b);
        System.out.println(a1);
        System.out.println(a2);
    }
}

예시는 다음과 같다.

자바에서 자동박싱,언박싱을 지원해주기때문에, valueOf만 알고있어도 큰 상관은 없으나, Wrapper class와 기본형의 메모리차이가 5배정도? 난다는 글을읽은것같다.. 따라서, 꼭 필요한경우가아니면 parse로 변환해주는것도 고려해보자.

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

[Java] Future.cancel() vs CompletableFuture.cancel()  (0) 2023.02.15
[Java] 스레드와 Synchronized  (0) 2021.10.25
[Java] Java Heap Stack Static  (0) 2021.10.23
[Java] compareTo  (0) 2021.05.05
[Java] ArrayList  (0) 2021.05.02