Java:: Integer equals vs == (Integer 내부 구조를 알아보자)

류영준·2023년 1월 31일
0

JAVA

목록 보기
9/9
post-thumbnail

들어가며

알고리즘 문제를 풀다가 Integer 객체에 대한 정수값을 비교해야 하는 일이 발생했다.

Integer a = 1;
Integer b = 1;

System.out.println(a == b);

출력 값은 true 가 된다.

Wrapping class인 Integer 타입에서 == 비교는 객체의 주솟값을 비교하는 것인데, 출력 값이 true 가 나오게 되어 당황스러웠다. 그 이유를 알아보기 위해 Integer 객체의 내부 구조를 파헤쳐보았다.


왜일까?

Java에서 정수형을 비교하는 방법은 2가지가 있다. ==equals

== 연산자는 Primitive type에서 값으로 비교하고, Wrapper Class에서는 각 객체의 주소 값으로 비교한다.

equals 메소드는 각 객체 간의 값을 비교할 때 사용된다. 이를 Primitive type인 int 비교에 사용하면 참조할 수 없다고 오류가 발생한다.

그렇다면 다음 예시를 살펴보자.

Integer a = 100;
Integer b = 100;

if (a == b)  System.out.println("a and b are the same.");
if (a != b)   System.out.println("a and b are different.");
if(a.equals(b))  System.out.println("a and b contain the same value.");

출력값은 다음과 같다.

a and b are the same.
a and b contain the same value.

“a and b are the same.” 의 결과가 나오는 이유는 Java Integer 객체 내부의 Caching에 있다.

Integer 객체 내부에 inner class로 정의되어 있는 IntegerCache 객체를 보면 다음과 같은 구조로 구현되어 있다.

Integer a = 10; 혹은 Integer a = Integer.valueOf(10); 와 같이 선언을 하면, 256개의 Integer 객체가 -128에서 127까지 생성되며 모두 Integer 배열에 저장된다. 위의 이미지를 보면, cache 배열에 저장되는 것을 알 수 있다.

따라서 Integer.valueOf() 를 사용하여 객체를 생성하거나 -128에서 127 범위 내에서 Integer에 직접 값을 할당하면 동일한 객체가 반환된다.

Integer a = 100;
Integer b = 100;

if (a == b)  System.out.println("a and b are the same.");
if (a != b)   System.out.println("a and b are different.");
if(a.equals(b))  System.out.println("a and b contain the same value.");

그러므로 위 예시에서 a와 b는 -128과 127 범위 내의 값이기 때문에 동일한 객체가 된다. 하지만 a와 b가 -128과 127 범위를 벗어나면 캐시가 사용되지 않으므로 새 객체가 생성된다. 그 때는 equals 메소드를 사용해서 값을 비교해야 한다.


결론

Integer Wrapping class에서 == 연산자로 비교를 하는 경우에는 -128 ~ 127 사이의 값을 제외하고는 원하지 않은 결과가 발생할 수 있다. 고로 객체를 비교할 때는 equals() 메소드를 사용해서 비교를 하는 것이 좋을 것 같다.ㅋ

profile
Backend Developer

0개의 댓글