본문 바로가기

p-languages/java

java/ Integer를 '==' 연산자가 아닌 'equals' 메서드로 비교해야 하는 이유 (Integer Cache)

 

 

 

Integer 값을 비교할 때 'equals' 메서드를 사용하지 않고 '==' 연산자를 사용해 코드를 작성한 경우, 일부 값은 정확하게 비교가 되는 반면 일부 값에 대해서는 같은 값임에도 false를 반환하는 경우가 있었다. 

 

e.g. 일부 값 (-128~127)에 대해서는 '==' 연산자로 비교 가능하고, 일부 값에서는 가능하지 않음

public static void main(String[] args) {
    Integer a = 10;
    Integer b = 10;

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

    Integer x = 128;
    Integer y = 128;

    System.out.println(x==y); //false
    System.out.println(x.equals(y)); //true
}

 

 

* 들어가기에 앞서 '==' 연산자는 참조, 즉 객체의 주소 값을 비교하고 'equals' 메서드는 객체의 값(데이터)를 비교한다는 사실을 짚어둔다.

 

그렇다면 위 코드의 경우 Wrapper 타입인 Integer 객체에 '==' 연산자를 사용하는 경우 모두 false 값이 반환되고, 'equals' 메서드를 사용하는 경우에만 true 값을 반환하는 것이 논리적으로 보인다. 하지만 위 코드의 경우 '10'의 경우에는 '==' 연산자로도 true 값이 반환된다.

 

왜 그런 일이 발생했는지, Java의 내부적인 동작 방식을 알아보자.

 

 


 

Integer Cache

ref.

 

In Java 5, a new feature was introduced to save the memory and improve performance for Integer type objects handling. Integer objects are cached internally and reused via the same referenced objects.

- This is applicable for Integer values in the range between –128 to +127.
- This Integer caching works only on auto-boxing.
- Integer objects will not be cached when they are built using the constructor.

 

 

 

즉, 설명에 따르면 Integer 객체는 내부적으로 cache되고, 참조 객체를 통해 재사용된다는 것을 알 수 있다. 

 

 

또한, 

 

적용 범위는 -128에서 127,

autoboxing, 즉 원시 타입(primitive type)에서 참조 타입(reference type)으로의 변환에서만 작동하며,

생성자를 통한 선언에서는 cache 되지 않는다.

 

 

e.g. 생성자를 통한 Integer 객체 생성 시 -128~127 사이의 값임에도 '==' 연산자로 비교되지 않음

public static void main(String[] args) {
    Integer i = 100;
    Integer j = new Integer(100);
    Integer k = 100;

    System.out.println(i==j); //false
    System.out.println(i==k); //true
}

 


 

결론

 

Integer 객체에 할당할 값이 -128~127 사이로 고정적인 범위를 갖는 경우 '==' 연산자로 무리 없이 값 비교가 가능하다. 하지만, 내부 로직의 변화나 추후 허용 값의 범위가 변경될 경우를 고려해 'equals' 메서드를 사용하는 것이 안전하다.

 

 


ref.