Design Pattern

Integer 객체

발표중 이슈로 나온 Integer 에 관해서 정리 간단하게 했습니다.

public static void main(String[] args) {
        Integer i1 = 1;
        Integer i2 = 1;
        Integer i3 = new Integer(1);        //deprecatged
        Integer j = 2;
        Integer k1 = 1200;
        Integer k2 = 1200;

        System.out.println(i1 == i2);       //true
        System.out.println(i1 == i3);       //false
        System.out.println(i1.equals(i2));  //true
        System.out.println(i1.equals(i3));  //true

        System.out.println(k1 == k2);       //false
        System.out.println(k1.equals(k2));  //true
    }

여기서 i1가 i2를 동일성 비교하면 true가 나오는데 또 k1과 k2를 비교하면 false가 나오는 것을 볼 수 있습니다.

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

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

            // Load IntegerCache.archivedCache from archive, if possible
            CDS.initializeFromArchive(IntegerCache.class);
            int size = (high - low) + 1;

            // Use the archived cache if it exists and is large enough
            if (archivedCache == null || size > archivedCache.length) {
                Integer[] c = new Integer[size];
                int j = low;
                for(int i = 0; i < c.length; i++) {
                    c[i] = new Integer(j++);
                }
                archivedCache = c;
            }
            cache = archivedCache;
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

이는 Integer 내부 static class로 IntegerCache를 가지고 있고 jvm이 올라갈때 -127 ~ 127(default)/127보다 높게 설정한 값 은 미리 Wrapper 객체를 만들어두고 boxing/unboxing시에 이를 사용하기 때문입니다.

   public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

valueOf()메서드를 보면 Cache에 값이 있는지 비교후 없으면 새로운 객체를 만드는 것을 볼 수 있습니다. 그리고 new Integer(1)과 같이 직접 생성자를 사용하려고 할때 IDE로 ntelliJ를사용한다면 생성자가 deprecated 되었다고 설명을 주며, 굳이 boxing 할 필요없다고 Unboxing을 제안하는 것을 볼 수 있습니다.

Last updated