Integer Object 127과 128
친구에게 갑자기 이 질문을 받게 되었다.
Integer a1 = 127;
Integer a2 = 127;
a1 == a2 는 true일까?
Integer b1 = 128;
Integer b2 = 128;
b1 == b2 는 true일까?
오브젝트 비교는 알겠는데.. 진짜 같은가에 대해선 대답을 못해서 우선 코드를 돌려보았다.
class Test {
public static void main(String[] args) {
Integer a1 = 127;
Integer a2 = 127;
System.out.println(a1 == a2); // true
Integer b1 = 128;
Integer b2 = 128;
System.out.println(b1 == b2); // false
}
}
결과가 왜이러는지 관련 내용을 찾아봤다.
우선 Integer a1=127 을 하게 되면 Auto-boxing 하게 되어 Integer.valueOf(127); 을 적용하게 된다.
이때, valueOf() 안의 함수를 보면
@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
위에와 같은 라는 함수를 볼 수 있습니다.
먼저 int값을 비교하여 IntegerCache.low, IntegerCache.high 랑 비교해보고, 조건문에 포함되지 않으면 새로운 객채를 반환합니다.
그럼 IntegerCache 가 뭔지를 확인해보면
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
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);
// Maximum array size is Integer.MAX_VALUE
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++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
위의 IntegerCache를 보면 java.lang.Integer.IntegerCache.high 를 통해서 high 값을 설정할수 있고( java1.6 버전때부터 지원) Vm.getSaveProperty를 통해 받은값과 127 값을 비교하고, Integer.MAX_VALUE - (-low) -1 (2147483518) 과 i값중 작은 값을 high로 정하고 있습니다.
기본적으론 -128 ~ 127의 값들이 미리 객체를 생성하여 cache[] 에 저장하고 있습니다.
이 결과 때문에 위에서 비교한 127의 Integer값들은 동일한 object를 가졌기에 true, 128을 매핑한 Integer값들은 다른 object를 가졌기에 false가 발생했던것..
궁금증 1. 그럼 다른 Class들은?
궁금해서 찾아보니 ShortCache, LongCache등 다른 클레스에도 적용이 되어있었다.(Double은 없었다. 당연한건가)
궁금증 2. 근데 왜 음수는 고정인가?
궁금증이 있어서 한번 검색해봤다
참고 사이트 : https://meetup.toast.com/posts/185, https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html