서론
이전 글에서
https://lovelyunsh.tistory.com/163?category=1042316
[JAVA] String도 Object 인데 왜 equals 함수로 값 비교가 가능할까?
의문 위 코드 같이 class를 생성하여 equals 함수를 사용하면 false가 나오게 되는 반면 String은 true가 나오게 된다. Object간 비교는 내부의 값이 아닌 객체를 가르키는 주소값으로 비교하기 때문으로
lovelyunsh.tistory.com
String도 결국 그렇게 특별하진 않았다. 라고 했는데
다시 생각해보니 String은 아주 특별하다.(?)
갑자기 이런 생각이 왜 들었냐 하면
이 코드를 보면서 문득 생각이 나게 됐다.
이전에 자바를 처음 배우며 얼핏 들었던 기억으로
String a = "hello world";
형태로 String을 선언하면
내부적으로 String pool에 "hello world" 객체를 넣어놓고 이후에
String b = "hello world";
같은 String 값이 들어오면 새로운 객체를 만들지 않고 pool에 있는 만들어져 있는 객체를 가리키게 한다.
그래서 a==b를 하면 같은 인스턴스이기 때문에 true가 출력이 된다.로 알고 있었는데
생각해보면 String도 Object인 주제에 원시타입 같이 = 연사자를 이용해 값을 담는게 가능하네?라는 생각이 들게 됐다.
이 개념을 확실히 정리할 겸 찾아보았다.
본론
https://pjh3749.tistory.com/255
[Java] 자바의 String 클래스의 특별성 간단 정리
https://www3.ntu.edu.sg/home/ehchua/programming/java/J3d_String.html String is Special - Java Programming Tutorial A Brief Summary of the String Class A Java String contains an immutable sequence of..
pjh3749.tistory.com
설명은 이 글에서 너무 재밌게 잘 돼있어서 한번 읽어보면 좋을 것 같다.
내가 이해한 내용을 정리하면
1. String은 절대적 불변하다.
이미 만들어진 String의 값은 절대 바뀌지 않는다.
그렇기 때문에 toUpperCase() 같은 함수를 쓰면 기존의 값이 변하는게 아닌
toUpperCase()가 적용된 새로운 객체를 만들어 반환한다.
cf) 생성된 새로운 객체는 역시나 pool이 아닌 새로운 객체로 생성된다.
2. 연산자 오버로딩이 되어있다.
일반적으로 Java에서는 연산자 오버로딩을 불가능하게 막아놨다.
( C++에선 허용 되어있어 +연산자에 - 연산을 넣는 행위가 가능하다.)
다만 예외적으로 String에서는 두 String을 이을 수 있게 + 연산이 오버로딩 되어있다.
= 연산자도 오버로딩 되었다 볼 수 있을 것 같다.
3. 생성 방식에 따라 String Constant pool이냐 새로운 객체를 생성하느냐가 갈린다
new를 이용해 새로운 객체 생성 시 heap영역에 객체 생성이 일어나고
리터널 생성방식을 이용하면 Common pool에서 생성을 하고
같은 값이면 참조만 하는 방식으로 생성을 한다.
cf) String Constant Pool은 Java7 버젼 이후 Perm영역에서 heap영역으로 이동되었다고 한다.
Perm영역은 Java8 버젼 이후 완전히 사라지고 MetaSpace라는 영역이 되었다고 한다.
즉, String Pool 역시 Garbage Collection의 관리하에 들어가게 된다.
4. 불변한 String의 성질을 보완하기 위해 StringBuilder와 StringBuffer가 존재한다.
둘의 차이는 thread-safe한지 안한지 StringBuffer가 thread-safe 하다.
이 둘은 다른 객체와 같이 힙영역에 생성되어 값 변화에 의한 사이드이펙트를 걱정하지 않아도 된다.
일반적으로 String + 연산에 비해 StringBuilder의 append를 사용하는 것이 효율적이다.
그런데 String의 + 연산도 내부적으로는 StringBuffer의 append를 사용한다고 한다.
String msg = "a" + "b" + "c";
String msg = new StringBuffer().append("a").append("b").append("c").toString();
그렇다면 동기처리 만큼의 효율성 차이가 있다고 보면 될 것 같다.
결론
String은 특별하다.
것두 아주 특별취급을 받고 있다.
내부적으로 알아가면서 재밌는 사실을 많이 알 수 있었다.
String 같이 특별취급을 받는 다른 친구가 있는지 찾아봤지만 정보가 딱히 나오진 않았다.
관련 정보가 있으시다면 댓글로 남겨주세요 !
'개발 이모저모 > 뻘 짓 연구' 카테고리의 다른 글
[Java] Priority Queue 들여다 보기 (1) | 2021.10.14 |
---|---|
[JAVA] 이차원 배열의 모든 크기는 일정해야하지 않나? (0) | 2021.09.10 |
[JAVA] String도 Object 인데 왜 equals 함수로 값 비교가 가능할까? (1) | 2021.08.15 |