| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- 오블완
- equals
- integer
- oracle
- 스레드
- HTML
- letterspacing
- MariaDB
- 키보드
- 컨트롤러
- START WITH
- 스레드 덤프
- wsdl
- 프로세스
- 안드로이드 스튜디오
- API
- 삼성증권
- Linux
- Docker
- 영상편집
- java
- Tomcat
- JDBC
- 티스토리챌린지
- http
- ibatis
- cmd
- Database
- MySQL
- 톰캣
- Today
- Total
블로그 이름
[JAVA] Integer 비교 시 ==가 아닌 equals() 를 사용하는 이유 본문
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 를 사용하여야 한다.
'개발 > Java' 카테고리의 다른 글
| [Java] 배열 내 존재여부 확인 시 List와 Set 동작방식 및 성능 차이 (0) | 2025.12.16 |
|---|---|
| [JAVA] 스레드 덤프 출력 및 분석 (데드락, 무한루프) (0) | 2025.11.16 |
| [JAVA] 객체의 메모리 크기 확인 방법 (1) | 2025.08.03 |
| [Java] Java 임시파일 경로 설정하기 (1) | 2025.06.09 |
| [JAVA] 윈도우 PC에 JAVA 설치 (0) | 2025.06.09 |