오늘의 나보다 성장한 내일의 나를 위해…













:pushpin: Integer의 ==와 .equals()


코딩 테스트를 공부하는 도중에 이해할 수 없는 일이 발생했다.

Integer의 동등 비교를 하는 if문에서 발생한 문제였는데 말로 설명하는 것보단 코드로 보는 것이 나을 것 같다.


참고로 아래 코드는 코딩 테스트 문제와는 관련이 없다.


HashMap<Integer, Integer> hs=new HashMap<>();
hs.put(5, 2500);
hs.put(1, 2500);

Integer aa = 2500;
Integer bb = 2500;

Integer cc = 3;
Integer dd = 3;

int aaa=3;
Integer bbb=3;

int aaaa=2500;
int bbbb=2500;

System.out.println(hs.get(5) == hs.get(1));
System.out.println(aa == bb);
System.out.println(cc == dd);
System.out.println(aaa == bbb);
System.out.println(aaaa == bbbb);


//결과
false
false
true
true
true


결과에서 이상한 점을 찾았는가?


사실 HashMap은 그냥 헷갈리라고 넣어봤다. 사실상 aa==bb한 것과 같다.


중요한 것은 aa==bb에서 false가 나온 것과 cc==dd에서 true가 나온 것이 헷갈린다.


우리가 기본적으로 ==연산은 주소를 비교하는 것으로 알고 있다.

Integer은 Wrapper Class니까 즉, 객체니까 주소를 비교한다.

그러니까 aa==bbfalse가 나오는 것이 납득이 간다.

하지만!cc==ddtrue일까?!!


이것도 분명 주소 비교를 할 텐데 말이다. true라는 것은 주소가 같다는 의미가 아닌가?..

해답은 바로 Java Integer 객체의 내부 Caching에 있다.

Java Wrapper Class Cahching 코드를 살펴보면 다음과 같은 구조로 구현되어 있다.


private static class IntegerCache
 {
   private IntegerCache(){}

   static final Integer cache[] = new Integer[-(-128) + 127 + 1];

   static
   {
     for(int i = 0; i < cache.length; i++)
     cache[i] = new Integer(i - 128);
   }
 }

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


즉, -128부터 127에 해당하는 정수값까지는 내부 캐시에 저장되어 있기 때문에 ==연산자로 비교를 해도 int 자료형과 마찬가지의 결과를 얻을 수 있지만 범위를 벗어나는 값들에 대해서는 false 값을 반환한다.


그렇다면 aaa==bbbb는 왜 true가 나오는 것일까?

그것은 바로 Primitive typeWrapper Class 사이의 값이 비교되기 때문이다. Primitive type의 경우 == 연산자는 을 비교한다.

만약 비교 대상 중에 Primitive Type의 변수가 하나라도 있다면 == 연산자는 으로 비교한다!

Primitive Type인 aaa와 Wrapper Class인 bbb는 값으로 비교하게 되는 것이다.


:pushpin: 결론

이런 것을 하나하나 다 기억하기는 어렵다.

중요한 것은 Wrapper Class을 사용해서 값 동등을 할 때는 equals() 메서드를 사용하는 것이 중요하다.


YoungKyonYou

Integration of Knowledge