프로그래밍언어/Java

Integer 비교하기 == 와 .equals()

Dev-SeeOne 2020. 6. 26. 22:24

먼저 다음 코드들의 결과를 유추해보자

 

Integer A = 1;
Integer B = 1;
System.out.println(A == B);
Integer A = 1000;
Integer B = 1000;
System.out.println(A == B);
Integer A = -128;
Integer B = -128;
System.out.println(A == B);
Integer A = 1;
Integer B = new Integer(1);
System.out.println(A == B);

 


 

각각의 결과 값은 다음과 같다.

  1. true
  2. false
  3. true
  4. false

왜 위와 같은 결과가 나왔을까?

 

먼저 1번부터 3번까지 해당하는 내용은 Java Integer 객체의 내부 Caching 에 있다. Java Wrapper Class Caching 코드를 살펴보면 다음과 같은 구조로 구현되어있다.

 

 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 값을 반환한다. 

 

4번 같은 경우에는 Primitive typeWrapper Class 사이의 값이 비교되기 때문에 false 값을 반환한다.

Primitive type의 경우 == 연산자는 값을 비교하고 Wrapper Class의 경우 == 연산자는 각 객체의 주소 값을 비교하게 되는데 값과 주소를 비교하게 되기 때문이다.

 

종종 Compareble 이나 Comparator 를 상속받아서 compareTo() 메소드나 compare() 메소드를 재정의 하는경우에서 혹은 위와 같이 그냥 Integer 객체를 == 을 사용해서 비교를 하는 경우가 있는데 특히나 위의 코드에서 처럼 원하지 않는 결과가 발생할 수 있기 때문에 객체를 비교할 때에는 equals() 메소드를 사용해서 비교를 해야 한다.