Wrapper Class란

기본형 타입(Primitive Type)을 객체 형태로 다룰 수 있도록 해주는 클래스

기본형 타입은 객체가 아니므로 객체 지향 프로그래밍 기능을 완전히 활용하기 어렵다.

 

왜 만들어 졌는지

이러한 기본형 타입을 객체로 다룰 수 있게 만들었다. 이로써

컬렉션 프레임워크, 메서드 호출 등의 객체 지향 기능을 활용할 수 있다.

유틸리티 메서드를 제공 받을 수 있다. (parseInt ...)

 

어떻게 사용하는지

  • boolean -> Boolean
  • byte -> Byte
  • char -> Character
  • short -> Short
  • int -> Integer
  • long -> Long
  • float -> Float
  • double -> Double

대문자로 시작하면 래퍼 클래스

        // 기본형 타입 -> 래퍼 클래스 객체 (Boxing)
    	Integer numObject = Integer.valueOf(num); // 명시적 박싱
        Integer autoBoxed = num; // 자동 박싱
        // 래퍼 클래스 객체 -> 기본형 타입 (Unboxing)
        int numValue = numObject.intValue(); // 명시적 언박싱
        int autoUnboxed = numObject; // 자동 언박싱

언제 사용하는 지

컬렉션 프레임워크와 사용

ArrayList, HashMap과 같은 컬렉션 클래스는 객체만을 다룰 수 있다.

기본형을 사용 못하므로 래퍼클래스를 사용해야 한다.

 

유틸리티 메서드를 사용하고 싶을 때

        String numberStr = "123";

        // 문자열을 int로 변환
        int number = Integer.parseInt(numberStr);
        System.out.println("Parsed int: " + number);

        // 문자열을 Integer 객체로 변환
        Integer numberObject = Integer.valueOf(numberStr);
        System.out.println("Integer object: " + numberObject);

 

더 알아두면 좋은 것

  • 래퍼 클래스는 불변이다.
    • 만들어진 객체는 바뀌지 않는다. 변경이 된다면 다른 객체를 만들어 그 곳을 가리키는 것 뿐
  • Integer에 경우 클래스 로딩 시 -128~127까지의 값이 정적 초기화 블럭에 캐싱 된다.
public class IntegerCacheExample {
    public static void main(String[] args) {
        Integer a = Integer.valueOf(127);
        Integer b = Integer.valueOf(127);

        System.out.println(a == b); // true, 동일한 객체를 참조

        Integer c = Integer.valueOf(128);
        Integer d = Integer.valueOf(128);

        System.out.println(c == d); // false, 다른 객체를 참조
    }
}

a, b에 경우 미리 캐싱된 값을 가리키기에 같이 값다. 주소가 같다는 것

c, d에 경우 캐싱된 값이 없기에 새로운 객체를 만들어 준다. 그렇기에 주소가 다르다.

정적 초기화 블록 (Static Initialization Block)

정적 초기화 블록은 클래스가 로드될 때 한 번 실행되는 코드 블록입니다. Integer 클래스의 내부에서 IntegerCache 클래스를 사용하여 이 범위의 값들을 미리 캐싱

public final class Integer extends Number implements Comparable<Integer> {
    private final int value;

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            int h = 127;
            String integerCacheHighPropValue = 
                VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    h = Math.min(i, Integer.MAX_VALUE - (-low) - 1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

    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 클래스가 로딩될 때, IntegerCache의 정적 초기화 블록이 실행됩니다. 이 블록에서는 -128에서 127까지의 Integer 객체를 생성하여 cache 배열에 저장합니다.
  2. 캐싱된 객체 사용: 이후, Integer.valueOf(int i) 메서드가 호출되면, i가 -128에서 127 사이의 값인 경우, cache 배열에서 해당 값을 반환합니다. 이 범위를 벗어나는 값에 대해서는 새로운 Integer 객체를 생성합니다.

'공부일지 > Java' 카테고리의 다른 글

[JAVA] String, StringBuffer, StringBuilder  (0) 2024.07.01
[JAVA] 6/21에 배운 것  (0) 2024.06.26
[JAVA] 6/20 배운거 클래스  (0) 2024.06.20
[JAVA] 인터페이스와 객체지향  (0) 2024.06.19
[JAVA] 추상클래스와 인터페이스  (0) 2024.06.19

+ Recent posts