기본
public static void main(String[] args) {
String a = "hello";
String b = " java";
String result1 = a.concat(b);
String result2 = a + b;
System.out.println("result1 = " + result1);
System.out.println("result2 = " + result2);
}
비교
public static void main(String[] args) {
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("new String() == 비교 " + (str1 == str2));
System.out.println("new String() equals 비교 " + (str1.equals(str2)));
String str3 = "hello";
String str4 = "hello";
System.out.println("리터럴 == 비교 " + (str3 == str4));
System.out.println("리터럴 equals 비교 " + (str3.equals(str4)));
}
new String() == 비교 false
new String() equals 비교 true
리터럴 == 비교 true
리터럴 equals 비교 true
new String
으로 생성한 것은 각각의 인스턴스를 갖는다. 그러므로 str1
과 str2
는 서로 다른 인스턴스 이므로 동일성 ==
비교에 실패한다.
- 내부에 같은
"hello"
를 가지고 있으므로 논리적으로 같다. 따라서 동등성 비교 equals
비교에는 성공한다.
문자열 풀(String Pool)
String str3 = "hello"
와 같이 문자열 리터럴을 사용하는 경우 자바는 메모리 효율성과 성능 최적화를 위해 문자열 풀을 사용한다.
- 자바가 실행되는 시점에 클래스에 뭄ㄴ자열 리터럴이 있으면 문자열 풀에 String 인스턴스를 미리 만둘어 두고 같은 문자열이 있으면 새로 만들지 않고 찾아서 반환한다.
그러므로 str3
과 str4
는 "hello"
라는 문자열 리터럴을 똑같이 가지고 있으므로 같은 인스턴스를 참조를 사용한다.
- 문자열 풀 덕분에 같은 문자를 사용하는 경우 메모리 사용을 줄이고 문자를 만드는 시간도 줄어들기 때문에 성능도 최적화 할 수 있다.
- 따라서 문자열 리터럴을 사용하는 경우는 같은 참조를 사용하기 때문에
==
비교에 성공한다.
문자열은 항상 동등성 비교(equals 비교)를 해야한다.
public static void main(String[] args) {
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("메서드 호출 비교1: " + isSame(str1, str2));
String str3 = "hello";
String str4 = "hello";
System.out.println("메서드 호출 비교1: " +isSame(str3, str4));
}
private static boolean isSame(String x, String y) {
return x == y;
}
- 메인 메서드와
isSame
메서드를 만드는 개발자가 달라 이렇게 개발이 되어있다고 생각해 본다면 isSame()
의 경우 매개변수로 넘어오는 String
인스턴스가 new String()
으로 만들어진 것인지, 문자열 리터럴로 만들어진 것인지 확인할 수 없다.
- 그러므로 문자열 비교는 항상
equals()

를 사용해서 동등성 비교를 해야한다.
참고- 김영한의 실전 자바 - 중급 1편