객체의 참조 비교: == 연산자는 객체의 메모리 주소를 비교합니다. 즉, 두 객체가 동일한 객체를 참조하는 경우에만 true를 반환합니다. 객체의 내용이 동일하더라도 서로 다른 메모리 주소를 가리키면 false를 반환합니다.
1. 정수(Integer)
- 기본형 정수: Java의 기본형 정수 타입(int, long 등)은 스택 메모리에 저장됩니다. 메서드가 호출될 때마다 스택 프레임에 할당되며, 메서드가 종료되면 해당 스택 프레임이 제거되면서 메모리도 해제됩니다.
- 래퍼 클래스: Integer와 같은 래퍼 클래스는 객체이기 때문에 힙 메모리에 저장됩니다. 래퍼 클래스의 경우, -128부터 127까지의 값은 캐싱되어 스트링 풀과 유사한 방식으로 재사용됩니다. 이 범위를 초과하는 값은 새로운 객체가 생성되므로, 각기 다른 메모리 주소를 가지게 됩니다.
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true: a와 b는 동일한 객체를 참조함
- 범위를 벗어난 경우: -128 미만 또는 128 이상의 정수 리터럴은 새로운 객체를 생성하므로 서로 다른 객체를 참조합니다.
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false: c와 d는 서로 다른 객체를 참조함
2. 문자열(String)
- 문자열 리터럴: 문자열 리터럴은 JVM의 스트링 풀이라는 특별한 메모리 영역에 저장됩니다. 같은 문자열 리터럴은 항상 같은 객체를 참조합니다. 즉, 문자열 리터럴은 캐싱되며, 새로운 문자열 리터럴이 생성될 경우 기존의 문자열과 동일한 내용이라면 스트링 풀에서 기존 객체를 참조하게 됩니다.
String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2); // true (같은 객체를 참조)
- new 키워드를 사용한 문자열: new String("Hello")와 같이 문자열 객체를 생성하면, 항상 새로운 객체가 힙 메모리에 저장됩니다. 이 경우에는 스트링 풀의 캐싱을 사용하지 않으므로, 같은 내용을 가진 문자열이라도 서로 다른 메모리 주소를 가집니다.
String str3 = new String("Hello");
String str4 = new String("Hello");
System.out.println(str3 == str4); // false: str3과 str4는 서로 다른 객체를 참조함
결론
- 정수: -128부터 127까지는 같은 객체, 그 외의 정수는 다른 객체.
- 문자열: 같은 문자열 리터럴은 항상 같은 객체, new 키워드를 사용하면 항상 새로운 객체.
'Java' 카테고리의 다른 글
함수형 인터페이스 (0) | 2024.11.25 |
---|---|
JVM 메모리 구조 (0) | 2024.11.02 |
기본형 VS 참조형 (1) | 2024.10.31 |
@SQLDelete (0) | 2024.09.09 |
epuals()와 hashCode() 오버라이딩 (0) | 2024.03.07 |