자바에서 `Integer`와 같은 래퍼 클래스를 활용해 숫자를 다룰 때 `==` 연산자로 값을 비교하면 예상치 못한 결과가 나올 때가 있거든요. 특히 127 이하의 작은 숫자는 비교가 성공하지만, 그보다 큰 숫자를 비교할 때는 결과가 달라지는 현상을 자주 보게 되는데요. 이는 자바가 성능 최적화를 위해 특정 범위의 숫자를 캐싱하는 정책을 가지고 있기 때문이에요. `Integer` 클래스는 `Integer.valueOf()` 메서드를 통해 호출될 때 -128부터 127 사이의 숫자를 미리 생성된 객체에서 가져와 재사용하게 되거든요. 이 범위 내에 있는 숫자들은 같은 인스턴스를 공유하기 때문에 `==` 연산자로 비교해도 동일한 값으로 인식되는 것이고요. 이는 메모리 사용량을 줄이고 객체 생성을 최소화하려는 의도가 담긴 설계예요. 따라서 개발 과정에서 숫자의 범위가 보장되지 않는 상황이라면 더욱 주의가 필요해요.

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

Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false

반면 128 이상의 숫자는 해당 캐시 범위에 포함되지 않기 때문에 매번 새로운 객체로 생성되게 돼요. 이 경우 `==` 연산자는 값의 비교가 아니라 메모리 주소를 비교하게 되므로 서로 다른 객체로 판단하여 `false`를 반환하게 되는 것이죠. 이러한 동작 방식 때문에 특정 범위 내에서는 `==`가 작동하는 것처럼 보이지만, 실제로는 객체 재사용이라는 특수한 상황에 의존하고 있는 것이에요. 이 현상은 특히 `int`와 `Integer` 사이의 자동 박싱 과정에서 발생하기 때문에 더욱 주의 깊게 살펴야 해요. `int`는 기본형(primitive type)이고 `Integer`는 래퍼 클래스(wrapper class)이기 때문이에요. 따라서 래퍼 클래스를 사용하여 숫자를 비교할 때는 항상 `equals()`를 사용하는 것이 원칙이에요. `equals()` 메서드는 메모리 주소가 아닌 실제 객체가 가지고 있는 내부 값을 비교하기 때문에 숫자의 크기에 상관없이 정확한 비교 결과를 보장해 준답니다.

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

결론적으로 자바에서 래퍼 클래스를 활용할 때는 해당 클래스가 제공하는 기능뿐만 아니라 내부적인 동작 원리도 함께 이해하는 것이 중요해요. `Integer`나 `Long` 같은 클래스는 내부적으로 캐싱 메커니즘이 작동하고 있기 때문에, 단순한 비교가 필요한 상황이라면 항상 `equals()`를 사용하는 습관을 들이는 것이 안전해요. 이렇게 하면 코드의 가독성을 높일 뿐만 아니라, 숫자의 크기에 관계없이 의도한 대로 정확하게 동작하는 코드를 작성할 수 있답니다.

+ Recent posts