📝느낀 점
String 객체를 생성하는 방식에 대해 리터럴 방식과 new 연산자 방식이 있다는 것을 알고 있었지만, 정확히 JVM 내부 동작 원리까지는 전혀 알지 못하고 있었다. 솔직하게 JVM까지 알아야 되는건가 하는 생각이 컸다, 하지만 예전의 나와 현재 내부 동작을 알게된 후로는 생각 방식 자체가 달라졌다는 것이다. 어떤식으로 저장 되는지, 어떤식으로 가져와 지는지, 메모리 관리 부분에 대해 더 깊이 알게 되어 좀 더 전문성이 생기지 않았나 하는 기분도 들게 되었다. 중요한것은 string에 대한 지식이 생겨 어떻게 String을 사용 시 메모리 및 시간에 대한 낭비가 발생하지 않을까? 하는 생각도 하게 되었다. 앞으로도 JVM에 더 깊은 공부를 해야 겠단 생각을 한다.
두 가지 방법이 있습니다.
String은 다른 참조 자료형과 달리 new연산자 외에도, 리터럴 생성 방식이 있다.
String a = "hello"
String a = new String("hello");
리터럴 생성 방식은
만들어진 객체가 저장되는 공간이 바로 String Pool 이라는 곳이다.
String Pool은 힙 메모리에 위치하고 있지만, new연산 역시 힙 메모리에 객체가 생성되는데,
String Pool에 저장되지는 않는다.
String의 리터럴 생성
String을 리터럴로 생성 시, 내부적으로 intern()메소드를 호출하게 된다.
intern()메소드는 String Pool에서 찾아보고, 존재하면 해당 문자열의 주소값을 반환,
존재하지 않으면 String Pool에 그 값을 생성하고 새로운 주소값을 할당하여 반환해준다.
즉, 리터럴 생성으로 동일한 값의 두 String을 생성한다면, 값만 같은 서로 다른 객체를 생성하는 것이 아니라,
String Pool 내부에 존재하는 객체의 주소값을 할당 받게 되는 것이다.
생각해보기
String a = "hello";
String b = "hello";
String c = new String("hello");
String d = new String("hello");
System.out.println(a == b); //true
System.out.println(b == c); //false
System.out.println(c == d); //false
선언할 때는 변수에 값을 저장하는 방식이 아닌 하나의 객체를 생성하고,
해당 객체인 주소값을 연결 시켜주는 방식이다
String 불변 객체
String 변수 = new String("문자열");
String 변수 = "문자열";
String 인스턴스는 한 번 생성되면, 그 값을 읽기만 할 수 있고, 변경할 수는 없다.
- 이러한 객체를 ”불변 객체" 라고 한다.
캐싱 기능에 의한 메모리 절약과 속도 향상
Pool에 있는 객체를 사용하기 때문에 특정 문자열 값을 재사용하는 빈도가 높을 수록 성능 향상을 기대할 수 있다.
thread-safe
String 객체는 불변이기 때문에 여러 쓰레드에서 동시에 특정 String 객체를 참조하더라도 안전하다.
즉, 덧셈 연산자를 사용해서 문자열과 문자열을 더한다면, 새로운 String 인스턴스가 생성되는 것이다.
아래 예시를 보면 str1, str2를 더한 str3은 새로운 인스턴스인 것입니다.
String str1 = "Hello";
String str2 = "JAVA";
String str3 = str1 + str2; // "HelloJAVA"
Reference
https://madplay.github.io/post/java-string-literal-vs-string-object
'Java' 카테고리의 다른 글
클래스와 메소드의 사용 이유는 무엇인가요? (0) | 2023.11.06 |
---|---|
char타입은 정수인가요? (0) | 2023.11.06 |
생성자를 왜 만들어야 하나요? / 컴파일러는 왜 기본 생성자를 자동으로 생성해 주나요? (0) | 2023.11.06 |
DTO를 만들어 두면 무슨 장점이 있나요? (0) | 2023.11.06 |
상속 정의 / 상속이 갖는 단점들은 무엇인가요? (0) | 2023.11.06 |