블로그 이름

[JAVA] Integer 비교 시 ==가 아닌 equals() 를 사용하는 이유 본문

개발/Java

[JAVA] Integer 비교 시 ==가 아닌 equals() 를 사용하는 이유

Hide 2025. 8. 31. 18:16

int, Integer 차이와 Integer 비교 시 ==가 아닌 equlas()를 사용하는 이유를 함께 알아보고자한다. 

 

보통 정수형은 ==를 사용하여 비교한다. String 객체는 equals를 사용하여 비교하는데, int는 보통 ==를 사용하여 비교했다.

 

기본타입을 wrapper class로 바꾸면 아래와 같이 된다.

기본타입 Wrapper Class
byte Byte
short Short
int  Integer
long  Long
float  Float
double  Double
char  Character
boolean  Boolean

 

기본 타입은 산술연산이 가능하며 null로 초기화 할 수 없다.

Wrapper 클래스는 Unboxing 없이는 산술연산이 불가능하고 null 값을 처리할 수 있다. 

Integer 객체들끼리 산술연산이 가능한 것은 JDK 1.5 이후 자바에서 AutounBoxing 을 지원하기 때문.

 

아래 프로그램의 결과를 확인해보면 셋 다 TRUE 로 나올 것으로 예상하지만 TRUE, FALSE, TRUE 로 출력된다.

Integer A= 300;
int B = 300;
Integer C= 300;
Integer X = 10;
Integer Y = 10;

if (A == B) {
    System.out.println("true");
} else {
   System.out.println("false");
}
// true 출력됨

if (A == C) {
    System.out.println("true");
} else {
   System.out.println("false");
}
// FALSE 출력됨

if (X == Y) {
    System.out.println("true");
} else {
   System.out.println("false");
}
// TRUE 출력됨

 

여기서 A와 B 중, B가 int 기본형이기 때문에 A와 B 모두가 int로 변환되어 int형끼리의 연산으로 생각하고 비교한다. int형이 하나 있으면 int형으로 연산하는 것이다.

 

A와 C는 모두 참조 타입으로, 매번 새로 생성되기 때문에 주소 값이 다르다. 때문에 비교 시 주소값이 다르기 때문에 FALSE가 반환된다. (예외 상황은 아래 서술) 

 

여기서 참조 타입이란  실제 객체가 아닌 객체의 주소를 저장하고 있다. 

 

int 값을 반환하는 메서드에 관해 확인해보자면, 

parseInt()

string 형 객체에서 int형 값을 추출하는 메서드. static으로 Integer 생성 없이 파라미터만 넣어주면 메서드 실행 가능. Wrapper 클래스를 생성하지 않고 내용물만 string에서 int로 교체한다. 

Integer.parseInt("문자"); 와 같이 사용한다.

리턴값이 int형으로, 산술 연산이 가능하다.

 

valueOf()

Integer 클래스를 리턴해주기 때문에 산술 연산이 불가능하다.

 

intValue()

Integer 객체에서 int형 값을 추출하는 메서드. static이 아니므로 객체가 필요하며 Object 타입을 int로 변환한다.

int x = Integer객체.intValue(); 로 사용한다.

리턴값이 int 형으로, 산술 연산이 가능하다.

 

 

다시 문제로 돌아가서,

Integer A = 300; -> Integer A = Integer.valueOf(300); 으로 변환하는데 (원시타입을 참조타입으로 변환) 

이 때 Integer.valueOf() 메소드는 -128에서 127 사이의 int형 리터럴을 넘겨줄 때, 새로운 Integer 객체를 생성하지 않고 내부에 있는 IntegerCache 객체에서 Integer 객체를 반환한다.

 

 

-128~-127 범위는 정수 객체를 캐싱하기 때문에 주소값이 같으며, int형끼리 비교하는 것과 같은 결과가 나온다. 

 

X 와 Y는 둘 다 10으로, 캐싱된 INTEGER 객체를 가져오기 때문에 주소값이 같아, == (주솟값 비교) 시 TRUE이지만, 

A와 C는 둘 다 300으로, 값만 봐서는 같아 보이지만 신규 생성된  INTEGER 객체로 주소값이 달라 FALSE 가 출력되는 것.

 

 

따라서 INTEGER 끼리의 비교에서는 == 사용 시, 의도한 결과가 나오지 않을 수 있다. (나도 디버깅 하면서 INTEGER == 가 제대로 되지 않고 있다는걸 알았다.)

 

String을 비교 시에만 equals를 사용하는 것이 아닌, 참조 타입, Integer 값끼리의 비교 시에도 equals 를 사용하여야 한다.