Home > Java > 기본 래퍼 클래스(Primitive Wrapper Class)

기본 래퍼 클래스(Primitive Wrapper Class)
java

기본 래퍼 클래스(Primitive Wrapper Class)는 8개의 기본형을 캡슐화(객체로 변환)하여, 이를 다른 클래스나 메서드에서 객체로 사용할 수 있도록 해주는 클래스이다 (feat. Wikipedia)

기본 래퍼 클래스의 메모리 저장 방식

  • 기본 래퍼 클래스(참고 : 참조형)는 Stack 영역에 실제 값이 저장된 공간의 주소를 저장하고, Heap 영역에 실제 값을 저장한다.
  • ex)

기본 래퍼 클래스 종류

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

오토 박싱(Auto Boxing), 오토 언박싱(Auto Unboxing)

박싱 : 기본형을 기본 래퍼 클래스의 객체(인스턴스)로 변환하는 것
언박싱 : 기본 래퍼 클래스의 객체(인스턴스)에 저장된 실제 값을 기본형으로 변환하는 것

  • 오토 박싱오토 언박싱은 자바 컴파일러가 상황에 따라 박싱과 언박싱을 자동으로 처리해주는 것을 의미한다. (JDK 1.5 버전부터 도입)
      Integer i_ref = 1000; // 오토 박싱
      // Integer i_ref = Integer.valueOf(1000);     // 박싱
    
      int i_pre = i_ref; // 오토 언박싱
      // int i_pre = i_ref.intValue();     // 언박싱
    
      int sum_prem = i_pre + i_ref; // 오토 언박싱
      // int sum_prem = i_pre + i_ref.intValue();     // 언박싱
    
      Integer sum_ref = i_pre + i_ref; // 오토 언박싱과 오토 박싱
      // Integer sum_ref = Integer.valueOf(i_pre + i_ref.intValue());     // 언박싱과 박싱
    

기본 래퍼 클래스(ex) Integer) 참고 사항

  • Java 9 버전부터는 기본 래퍼 클래스의 생성자 사용이 deprecated 처리되었다.
      Integer i1 = 777; 
      Integer i2 = Integer.valueOf(777); 
    
      Integer i3 = Integer.valueOf("777"); // 박싱
      Integer i4 = "777"; // 컴파일 오류
    
      Integer i5 = new Integer(777); // 컴파일 오류
      Integer i6 = new Integer("777"); // 컴파일 오류
    
  • 자바 컴파일러는 오토 박싱 시 생성자 대신 Integer.valueOf()를 사용하며, 해당 메서드는 캐싱된 Integer 객체를 반환한다.
    • JVM은 -128에서 127까지의 int 값에 대한 Integer 객체를 캐싱하고, 이러한 객체들은 Heap 영역의 내의 Constant Pool에 생성된다. 메모리 절약 및 속도 향상의 이점이 있다.
        Integer i1 = 127;
        Integer i2 = 127;
        System.out.println(i1 == i2); // 출력 : true -> i1과 i2는 같은 객체를 참조 -> 주소 비교
        System.out.println(i1.equals(i2));  // 출력 : true -> Integer의 값 비교
      
        Integer i3 = 128;
        Integer i4 = 128;
        System.out.println(i3 == i4); // 출력 : false -> i3와 i4는 다른 객체를 참조 -> 주소 비교
        System.out.println(i3.equals(i4)); // 출력 : true -> Integer의 값 비교
      
        // Integer 클래스의 valueOf() 메서드
        public final class Integer extends Number implements Comparable<Integer>, Constable, ConstantDesc {
            ...
            @IntrinsicCandidate
            public static Integer valueOf(int i) {
                if (i >= IntegerCache.low && i <= IntegerCache.high)
                    return IntegerCache.cache[i + (-IntegerCache.low)];
                return new Integer(i);
            }
            ...
        }
      
  • 기본 생성 클래스는 불변 객체이므로, 값이 변경되면 새로운 객체가 생성된다. 따라서, 잦은 연산은 성능 저하(메모리 낭비, 속도 저하 등)가 발생할 수 있다.

    • 예시 1 : 객체의 주소
        Integer i = 1000;
        System.out.println(System.identityHashCode(i)); // 출력 : 1915318863
      
        i += 500;
        System.out.println(System.identityHashCode(i)); // 출력 : 1283928880
      
    • 예시 2 : 연산 속도 비교 : 기본형 vs 기본 래퍼 클래스
        long startTime_pre = System.nanoTime();
              
        // 1. 기본형 연산
        int sum_pre = 0;
        for (int i = 0; i < 10_000; i++) {
            sum_pre += i;
        }
              
        long endTime_pre = System.nanoTime();
        System.out.println("기본형 실행 시간: " + (endTime_pre - startTime_pre) + " ns");   
        // ---------------> 기본형 실행 시간: 101979 ns
      
        long startTime_ref = System.nanoTime();
      
        // 2. 기본 래퍼 클래스 연산
        Integer sum_ref = 0; // Integer.valueOf(0);
        for (int i = 0; i < 10_000; i++) {
            // for문의 코드 실행할 때마다 새로운 객체 생성
                  
            sum_ref += i; // sum_ref = Integer.valueOf(sum_ref.intValue() + i);
        }
      
        long endTime_ref = System.nanoTime();
        System.out.println("기본 래퍼 클래스 실행 시간: " + (endTime_ref - startTime_ref) + " ns");   
        // ---------------> 기본 래퍼 클래스 실행 시간: 1822995 ns
      
              
        // 실행시간 차이가 크다.
            // 즉, 잦은 연산이 필요할 때 CPU와 메모리를 낭비하고 싶지 않다면 
            // 기본 타입인 int을 사용하거나 
            // 객체를 재사용할 수 있는 새로운 클래스를 정의해야 할 것이다.
      

  • 참고 자료
    https://stackoverflow.com/questions/13098143/why-does-the-behavior-of-the-integer-constant-pool-change-at-127
    https://stackoverflow.com/questions/3689745/what-exactly-does-comparing-integers-with-do
    https://stackoverflow.com/questions/3131136/integers-caching-in-java
    https://inpa.tistory.com/entry/JAVA-%E2%98%95-wrapper-class-Boxing-UnBoxing
    https://jaehoney.tistory.com/101