JAVA/in 기초

[Topic]왜 1000 == 1000 은 False이고, 100 == 100 은 True 일까?

lahuman 2015. 11. 25. 16:17
728x90

원문 : Why 1000 == 1000 Returns False, but 100 == 100 Returns True in Java?

이것은 아마도 많이 이야기 되는 흥미로운 내용일 것입니다.
다음의 코드를 실행하면

Integer a=1000, b=1000;
System.out.println(a == b); //1
Integer c=100, d=100;
System.out.println(c == d); //2

다음의 결과를 확인할 수 있습니다.

false
true

이해를 위한 기본: 두 개의 참조 값이 같은 객체를 가리키는 경우, 그것이 == 로 같은 것으로 알고 있습니다. 만약 두 개의 객체가 가르치는 참조가 다를 경우, 같은 내용을 가지고 있어도 == 로 같지 않다는 결과를 받습니다.

그래서 마지막 결괏값 역시 false 여야 합니다.

이 흥미로운 것은 사실이다. 만약 당신이 Integer.java 클래스를 본다면 IntegerCache.java 내부 private 클래스를 확인할 수 있을 것이며, 이 클래스에서 -128부터 127까지의 값을 캐시에 저장한다.

그래서 다음과 같이 우리가 뭔가를 선언 할 때 작은 숫자 값은 캐시에 저장된다.

Integer c = 100;

다음 실행하면 내부에서 어떤 일이 일어나는가?

Integer i = Integer.valueOf(100);

valueOf() 메소드를 확인하면

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

만약 값이 범위가 -128에서 127이라면 캐시에 저장된 객체가 전달 될 것이다.
그래서

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

에 결과로 우리는 true를 확인하였다.

당신은 “왜 캐시가 필수일까?” 라는 의문을 가질 것이다.
아마도, 논리적인 근거는 작은 값의 숫자 범위 값은 큰 숫자 하나 보다 더 많이 사용된다. 그래서 같은 객체를 이용하여 메모리 사용량을 줄이는 것이다.

그러나 reflections API를 이용하여 이 기능을 악용할 수 있습니다.

다음 코드를 실행하면, 재미있는 결과를 확인할 수 있습니다.

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
  Class cache = Integer.class.getDeclaredClasses()[0]; //1
  Field myCache = cache.getDeclaredField("cache"); //2
  myCache.setAccessible(true);//3
  Integer[] newCache = (Integer[]) myCache.get(cache); //4
  newCache[132] = newCache[133]; //5
  int a = 2;
  int b = a + a;
  System.out.printf("%d + %d = %d", a, a, b); //
}

결괏값

2 + 2 = 5



추가 내용 :

warpper class(Integer, Double, Long 등)의 인스턴스의 경우 값에 대한 비교는 equals() 메소드를 이용해야 합니다.


MARK DOWN FILE :

1000_100_Integer.md




728x90