์๋ฐ์์ String์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ํ์
์ค ํ๋์ด๋ค. ๋จ์ํ ๋ฌธ์์ด ํ์
์ด๋ผ๊ณ ์๊ฐํ๊ธฐ ์ฝ์ง๋ง ์ฌ์ค String์ Java ์ธ์ด ์ ์ฒด์์ ํน๋ณํ๊ฒ ์ทจ๊ธ๋๋ ๊ฐ์ฒด์ด๋ค.
String์ primitive ํ์
์ด ์๋ ์ผ๋ฐ ๊ฐ์ฒด์ด์ง๋ง JVM๊ณผ ์ปดํ์ผ๋ฌ๊ฐ ๋ฌธ์์ด ์ฒ๋ฆฌ๋ฅผ ์ํด ํน๋ณํ ์ต์ ํ ์ ๋ต์ ์ ์ฉํ๋ ํด๋์ค์ด๋ค. ์๋ฅผ ๋ค์ด ๋ฌธ์์ด ๋ฆฌํฐ๋ด ๊ด๋ฆฌ, String Pool, ์ปดํ์ผ๋ฌ ์ต์ ํ ๋ฑ์ด ๋ํ์ ์ด๋ค.
๋ํ String ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ด final ํด๋์ค๋ก ์ ์ธ๋์ด ์์ด ์์์ด ๋ถ๊ฐ๋ฅํ๋ค.
public final class String
์ด๋ ๋ฌธ์์ด์ ๋ถ๋ณ์ฑ์ ๋ณด์ฅํ๊ณ ๋ณด์๊ณผ ์์ ์ฑ์ ๋์ด๊ธฐ ์ํ ์ค๊ณ์ด๋ค. Java์ String์ด ์ ํน๋ณํ์ง ํต์ฌ ํน์ง์ ์ค์ฌ์ผ๋ก ์ดํด๋ณด์.
์ฒซ ๋ฒ์งธ ํน์ง์ String์ ๋ถ๋ณ ๊ฐ์ฒด๋ผ๋ ์ ์ด๋ค. ์ฆ ํ ๋ฒ ์์ฑ๋ ๋ฌธ์์ด ๊ฐ์ฒด๋ ์ ๋๋ก ๋ณ๊ฒฝ๋์ง ์๋๋ค.
์๋ฅผ ๋ค์ด โBlueโ๋ผ๋ ๋ฌธ์์ด์ "Cool"์ ๋ถ์ด๋ฉด ๊ธฐ์กด ๊ฐ์ฒด๊ฐ ์์ ๋๋ ๊ฒ์ด ์๋๋ผ ์์ ํ ์๋ก์ด String ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
String me = "Blue";
me += "Cool";
// ๊ฒฐ๊ณผ์ ์ผ๋ก "BlueCool"์ด๋ผ๋ ์๋ก์ด ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
์ด๋ฌํ ๋ถ๋ณ์ฑ์ ๋จ์ํ ์ธ์ด ํน์ฑ์ด ์๋๋ผ Java์ ์ฑ๋ฅ๊ณผ ์์ ์ฑ์ ์ค์ํ ์ญํ ์ ํ๋ค.
๋ ๋ฒ์งธ ํน์ง์ JVM์ด ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ ํ์์ ๊ด๋ฆฌํ๋ค๋ ์ ์ด๋ค. ์ด๋ฅผ String Intern Pool ๋๋ String Constant Pool ์ด๋ผ๊ณ ํ๋ค.
์๋ฐ ์ฝ๋์์ โBlueCoolโ ๊ฐ์ ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ด ์ฌ๋ฌ ๋ฒ ๋ฑ์ฅํ๋๋ผ๋ JVM์ ๋งค๋ฒ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋์ ํ ๋ฒ ๋ง๋ ๋ฌธ์์ด์ ํ์ ์ ์ฅํด๋๊ณ ์ฌ์ฌ์ฉํ๋ค.
String blue = "BlueCool";
String cool = "BlueCool"; // ๋ฌธ์์ด ํ์์ ๊ฐ์ ๊ฐ์ฒด ์ฌ์ฉ
System.out.println(blue == cool); // true
์ ์ฝ๋์์ โBlueCoolโ ์ด๋ผ๋ ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ์ค์ ๋ก String Pool์ ๋จ ํ๋๋ง ์กด์ฌํ๋ฉฐ blue์ cool ๋ณ์๋ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ == ๋น๊ต๋ true๊ฐ ๋๋ค.
์ด ๋ฉ์ปค๋์ฆ ๋๋ถ์ ๋ค์๊ณผ ๊ฐ์ ์ฅ์ ์ด ์๋ค.
== ๋น๊ต๋ก๋ ๋์ผ์ฑ์ ํ์ธํ ์๋ ์๋ค. ๋ฌธ์์ด์ new ํค์๋๋ก ์์ฑํ๋ฉด String Pool๊ณผ ๋ณ๊ฐ์ ์๋ก์ด ๊ฐ์ฒด๊ฐ Heap์ ์์ฑ๋๋ค.
String blue = "BlueCool";
String cool = "BlueCool";
String blueCool = new String("BlueCool");
System.out.println(blue == cool); // true (String Intern Pool)
System.out.println(blue == blueCool); // false (new ํค์๋๋ก ์์ฑ๋ ์ ๊ฐ์ฒด)
System.out.println(blue.equals(blueCool)); // true (๋ด์ฉ ๋น๊ต)
์ฌ๊ธฐ์ "BlueCool" ๋ฆฌํฐ๋ด์ Pool์ ์กด์ฌํ์ง๋ง new String("BlueCool")์ Heap์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
๋ฌธ์์ด ๋ฆฌํฐ๋ด์ Intern Pool์ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ == ๋น๊ต๋ก ๊ฐ์ ๊ฐ์ฒด์ธ์ง ํ์ธํ ์๋ ์์ง๋ง ์ผ๋ฐ์ ์ธ ๋ฌธ์์ด ๋น๊ต๋ equals()๊ฐ ์ ์์ด๋ค.
์ด์ ๋ new ํค์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ฌธ์์ด ๋ฆฌํฐ๋ด๊ณผ๋ ๋ณ๊ฐ๋ก ํญ์ ์๋ก์ด ๊ฐ์ฒด๊ฐ ์์ฑ๋๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฌธ์์ด์ ์ค์ ๋ด์ฉ์ ๋น๊ตํ ๋๋ ํญ์ equals()๋ฅผ ์ฌ์ฉํ๊ณ ์ฐธ์กฐ ๋์ผ์ฑ(๊ฐ์ ๊ฐ์ฒด ์ฌ๋ถ)์ด ํ์คํ ํ์ํ ๋๋ง == ์ ์ฌ์ฉํ๋ค.
ํ์ํ๋ค๋ฉด ๋ฌธ์์ด์ ์ง์ String Pool์ ๋ฑ๋กํ๊ฑฐ๋ Pool์ ์ฐธ์กฐ๋ฅผ ์ป์ ์๋ ์๋ค.
String a = new String("hello");
String b = a.intern();
System.out.println(a == b); // falseโ
intern()๋ฉ์๋๋ ํ์ฌ ๋ฌธ์์ด๊ณผ ๋์ผํ ๊ฐ์ด String Pool์ ์กด์ฌํ๋์ง ํ์ธํ ๋ค ์ด๋ฏธ ์กด์ฌํ๋ค๋ฉด Pool์ ์๋ ๋ฌธ์์ด ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ๋ฐํํ๋ค. ๋ง์ฝ Pool์ ํด๋น ๋ฌธ์์ด์ด ์๋ค๋ฉด Pool์ ์๋ก ๋ฑ๋กํ ๋ค ๊ทธ ์ฐธ์กฐ๋ฅผ ๋ฐํํ๋ค.
์ค์ํ ์ ์ intern()์ ํธ์ถํ๋๋ผ๋ ๊ธฐ์กด ๊ฐ์ฒด๊ฐ Pool๋ก ์ด๋ํ๋ ๊ฒ์ ์๋๋ผ๋ ๊ฒ์ด๋ค. ์ ์ฝ๋์์ a๋ ์ฌ์ ํ Heap์ ์์ฑ๋ new String("hello") ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ณ b๋ String Pool์ ์กด์ฌํ๋ "hello" ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ฒ ๋๋ค.
๋ฐ๋ผ์ ๋ ๋ณ์๋ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ฏ๋ก == ๋น๊ต ๊ฒฐ๊ณผ๋ false๊ฐ ๋๋ค.
์์ ์ดํด๋ณธ ๊ฒ์ฒ๋ผ String์ ๋ถ๋ณ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ ๋ฌธ์์ด์ ์ด์ด ๋ถ์ด๋ ์ฐ์ฐ์ ์ํํ ๋ ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์์ ํ๋ ๊ฒ์ด ์๋๋ผ ์๋ก์ด ๋ฌธ์์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
์๋ฅผ ๋ค์ด ๋ค์ ์ฝ๋๋ ๋ฐ๋ณต์ ์ผ๋ก ์๋ก์ด ๋ฌธ์์ด์ ์์ฑํ๊ฒ ๋๋ค.
String result = "";
for (int i = 0; i < 10000; i++) {
result += i; // ๋งค ๋ฐ๋ณต๋ง๋ค ์๋ก์ด String ๊ฐ์ฒด ์์ฑ
}
์ด ๊ฒฝ์ฐ ๋ฃจํ๊ฐ ๊ธธ์ด์ง์๋ก ๋ง์ ์์ ๋ฌธ์์ด ๊ฐ์ฒด๊ฐ ์์ฑ๋๊ณ GC ๋ถ๋ด์ด ์ฆ๊ฐํ๊ฒ ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์๋ฐ์์๋ ๊ฐ๋ณ ๋ฌธ์์ด ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ค.
๊ฐ์ฅ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ ๋ฌธ์์ด ์กฐ์ ํด๋์ค๋ค. ๋ด๋ถ์ ์ผ๋ก ๊ฐ๋ณ ๋ฒํผ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด์ ์ด์ด ๋ถ์ธ๋ค. ๋๊ธฐํ๊ฐ ํ์ ์๋ ๋จ์ผ ์ค๋ ๋ ํ๊ฒฝ์์ ๊ฐ์ฅ ๋น ๋ฅด๋ค.
StringBuilder์ ๊ฑฐ์ ๋์ผํ์ง๋ง ๋ชจ๋ ๋ฉ์๋๊ฐ ๋๊ธฐํ(synchronized) ์ฒ๋ฆฌ๊ฐ ๋์ด ์์ด ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ๋ฌธ์์ด ์กฐ์์ด ๋น๋ฒํ ๋ ์ฌ์ฉ๋๋ค.
๋ค๋ง ๋๊ธฐํ ๋น์ฉ ๋๋ฌธ์ ์ฑ๋ฅ์ด ๋จ์ด์ง๊ธฐ ๋๋ฌธ์ ํ๋ Java ์ฝ๋์์๋ ๋๋ถ๋ถ StringBuilder๋ฅผ ์ฌ์ฉํ๋ค.
๋จ์ํ + ์ฐ์ฐ์ ์ค์ ๋ก ์ปดํ์ผ ์ ๋ค์๊ณผ ๊ฐ์ด ๋ณํ๋๋ค.
String a = "Hello";
String b = a + "World";
์ปดํ์ผ๋ฌ๋ ์ด๋ฅผ ๋ด๋ถ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ๋ณํํ๋ค.
new StringBuilder()
.append(a)
.append("World")
.toString();โ
์ฆ ๋๋ถ๋ถ์ ๋ฌธ์์ด ๊ฒฐํฉ์ ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก StringBuilder๋ก ์ต์ ํํ๋ค.
ํ์ง๋ง ๋ฃจํ ๋ด๋ถ์์ ๋ฐ๋ณต์ ์ผ๋ก + ์ฐ์ฐ์ด ๋ฐ์ํ๋ฉด ๋งค ๋ฐ๋ณต๋ง๋ค StringBuilder ๊ฐ์ฒด๊ฐ ์๋ก ์์ฑ๋๊ธฐ ๋๋ฌธ์ ์ญ์ ์ฑ๋ฅ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
Java 9๋ถํฐ String์ ๋ด๋ถ ๊ตฌ์กฐ๊ฐ ํฌ๊ฒ ๊ฐ์ ๋์๋ค.
์ด๋ฌํ ์ต์ ํ๋ JVM ์์ค์์ ์๋์ผ๋ก ์ ์ฉ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ์๋ ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋๋ฉฐ ์ต์ Java์์ ๋ฌธ์์ด ์ฒ๋ฆฌ๊ฐ ๋ ๋น ๋ฅด๊ณ ํจ์จ์ ์ด๋ค.
