좋습니다!
그렇다면 다른 주제로 실기 스타일의 꼬아낸 기본기 문제를 드릴게요. 이번에는 **문자열(String) 비교와 참조 방식("==" vs .equals())**을 주제로 삼겠습니다.
이건 진짜 자바 실기에서 틀리기 딱 좋은 대표 함정이에요.
public class Main {
public static void main(String[] args) {
String a = "hello";
String b = "hello";
String c = new String("hello");
System.out.println(a == b);
System.out.println(a == c);
System.out.println(a.equals(c));
}
}
A.
true
true
true
B.
false
false
true
C.
true
false
true
D.
false
true
false
| 비교 방식 | 의미 |
|---|---|
== | 두 객체가 **같은 주소(참조)**를 가리키는지 비교 |
.equals() | 두 객체의 내용이 같은지 비교 (문자열 값 비교) |
String a = "hello";
String b = "hello";
"hello"는 String constant pool에 저장됨"hello" 객체를 참조함a ─────┐
▼
"hello"
▲
b ─────┘
✅ a == b → true
String c = new String("hello");
new String(...)을 쓰면 무조건 새로운 객체 생성c는 같은 내용이지만 다른 객체를 참조c ─────> "hello" (새 객체)
✅ a == c → false
System.out.println(a == b); // true
System.out.println(a == c); // false
System.out.println(a.equals(c)); // true (내용은 같음)
String x = "abc";
String y = x + "";
System.out.println(x == y);
"abc" 리터럴로 보이지만, 런타임에 새롭게 만들어진 객체x == y → false| 표현 | 의미 | 주소 같음? | 내용 같음? |
|---|---|---|---|
"abc" | 리터럴 | ✅ | ✅ |
new String("abc") | 새 객체 | ❌ | ✅ |
a == b | 참조 비교 | ✅ or ❌ | - |
a.equals(b) | 내용 비교 | - | ✅ or ❌ |
아주 좋은 질문입니다!
==와 .equals()는 자바에서 객체를 비교할 때 의미와 쓰임이 완전히 다릅니다.
== 연산자String a = "hello";
String b = "hello";
System.out.println(a == b); // true, 같은 상수풀(String constant pool)을 참조함
String c = new String("hello");
System.out.println(a == c); // false, c는 새로운 객체임
.equals() 메서드String a = "hello";
String c = new String("hello");
System.out.println(a.equals(c)); // true, 내용이 같으므로 true 반환
| 비교 방법 | 비교 대상 | 의미 | 결과 예시 (String a="hello", c=new String("hello")) |
|---|---|---|---|
== | 참조값 | 두 변수가 같은 객체인지 | a == c → false |
.equals() | 객체 내용 | 두 객체 내부 내용이 같은지 | a.equals(c) → true |
==.equals() (특히 String, Wrapper 클래스 등)==로 문자열 비교하면 잘못된 결과가 나와서 버그 원인이 됨if (str1.equals(str2)) { ... } // 안전하고 정확한 문자열 비교
// null 안전하게 쓰려면
if ("hello".equals(str1)) { ... } // str1이 null이어도 NPE 안남