Home [Java] Wrapper class valueOf 캐싱
Post
Cancel

[Java] Wrapper class valueOf 캐싱

Integer의 valueOf 캐싱

Integer의 valueOf는 -128부터 127사이의 값들을 미리 만들어두고 변환합니다. 아래 그림과 같이 말이죠.

1
2
3
public static Integer valueOf(int i) {
	return i >= -128 && i <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[i + 128] : new Integer(i);
}

IntegerCache는 -128부터 127까지의 값을 갖는 Integer 배열을 가지고 있습니다. 이 배열은 0번째 index에 -128의 값을 가진 Integer 객체가 있습니다. 즉, 1번째 index에는 -127, 2번째에는 -126, …

그래서 valueOf할 때 -128과 127사이의 값이 인자로 들어오면, 미리 만들어둔 IntegerCache.cache[i - 128]를 반환합니다.

1
2
3
4
5
6
7
8
9
Integer a = 120; // IntegerCache에서 꺼내온다
Integer b = 120; // IntegerCache에서 꺼내온다

System.out.println(a==b);	// true

Integer c = 500; // 새로운 객체 생성
Integer d = 500; // 새로운 객체 생성

System.out.println(c==d);	// false

이 코드에서 Integer변수에 값을 담을 때 autoboxing이 발생합니다. 그래서 실제로 a에는 120대신 Integer.valueOf(120)이 대입됩니다. 이때 120은 캐싱 범위내에 있으므로 IntegerCache에서 미리 만들어둔 Integer(120)을 꺼내옵니다.

따라서 a와 b는 같은 객체(IntegerCache[128+120])를 참조하지만, c와 d는 아얘 새로 만들어진 객체를 참조합니다.

Integer 캐싱 범위 변경하기

캐싱 범위를 바꿀 수도 있습니다. 최소 값은 -128로 고정되지만, 최대 값은 조절할 수 있습니다. VM에 아래 옵션을 주면 됩니다.

1
-XX:AutoBoxCacheMax=128	// 기본 값은 128.

다른 Wrapper Class도 캐싱된다.

Integer로 예시를 들었지만 Byte, Short, Long, Character도 캐싱됩니다. 아래는 각 wrapper class의 valueOf 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Long
public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}

// Byte
public static Byte valueOf(byte b) {
    final int offset = 128;
    return ByteCache.cache[(int)b + offset];
}

// Short
public static Short valueOf(short s) {
    final int offset = 128;
    int sAsInt = s;
    if (sAsInt >= -128 && sAsInt <= 127) { // must cache
        return ShortCache.cache[sAsInt + offset];
    }
    return new Short(s);
}

// Character
public static Character valueOf(char c) {
    if (c <= 127) { // must cache
        return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}

하지만 위의 class들은 범위를 변경할 수 없습니다. 오직 Integer만 최대 값을 변경할 수 있습니다.

This post is licensed under CC BY 4.0 by the author.