인프런 커뮤니티 질문&답변

인프린님의 프로필 이미지

작성한 질문수

김영한의 실전 자바 - 중급 1편

StringBuilder - 가변 String

String 질문

24.06.09 22:22 작성

·

167

0

안녕하세요.

String을 구현한 클래스 설명해주신 부분에서 이해가 안가는 게 있어서 문의드립니다.

StringBuilder와의 차이점에서 StringBuilder가 가변적일 수 있는 이유로 아래 필드가 final인지(String) 아닌지(StringBuilder)로 설명해주셨는데요.

final byte[] value라면 value 변수는 참조변수 일꺼고 그렇기에 참조값만 변경이 되지 않으면 참조하고 있는 객체의 내부 상태들은 변경이 가능할텐데 예를 들어

String a = newString("abc");

여기에서 c를 d로 바꾼다 한들 value가 참조하는 내용이 아닌 참조값도 바뀌어야 하는 이유가 궁금합니다.

StringBuilder의 경우에는 final 선언이 안 되어 있으니 value 필드의 참조값이 바뀌던 안바뀌던 상관 없을텐데 String 같은 경우에는 final이긴 하지만 value가 참조하는 내용을 바꿨다고 해서 참조값이 무조건 바뀌게 되는 이유가 궁금합니다.

private final byte[] value;

답변 2

1

김영한님의 프로필 이미지
김영한
지식공유자

2024. 06. 10. 19:54

안녕하세요. 인프린님

생각하신 내용이 맞습니다. 단순히 final 키워드 하나로 불변성이 완성되지는 않습니다. 만약 byte[] 안의 값을 변경해버린다면 다른 문자값이 되어버리는 것이지요.

String 클래스의 불변성은 단순히 final 키워드 때문만이 아니라, 클래스 설계 자체에서 내부 배열의 변경을 허용하지 않도록 하는 여러 가지 메커니즘에 의해 보장됩니다. private final로 선언된 배열은 외부에서 접근할 수 없으며, String 클래스의 모든 메서드는 불변성을 유지하도록 설계되어 있습니다.

따라서 이런 부분까지 모두 종합해서 생각해야 합니다.

감사합니다.

0

인프런 AI 인턴님의 프로필 이미지

2024. 06. 09. 22:26

안녕하세요, 인프런 AI 인턴입니다.

인프린님, String 클래스와 StringBuilder의 참조변수와 내부 상태 변경 및 final 키워드의 역할에 대해 질문해주셨네요. 이와 유사한 질문에 대한 답변을 이미 제공한 게시글을 찾았습니다.

먼저, String 클래스는 불변 객체(immutable object)입니다. 이는 한 번 생성된 String 객체의 상태가 변경되지 않음을 의미합니다. 즉, 만약 문자열의 내용을 변경하려 하면 새로운 String 객체가 생성되고, 기존 객체는 변경되지 않습니다. private final byte[] value; 필드는 String 객체에 저장된 문자열의 값을 담고 있는데, final이므로 참조 자체는 변경할 수 없습니다. 그럼에도 불구하고 String의 내용을 변경하는 것처럼 보이는 연산들(예: String a = "abc"; a = a + "d";)은 사실 새로운 String 객체를 생성하고, 이 객체가 새로운 내용을 담게 됩니다.

StringBuilder는 가변 객체(mutable object)로, 객체가 한 번 생성된 후에도 내부 상태를 변경할 수 있습니다. 이는 StringBuilder가 내부적으로 보유한 배열(value)의 내용을 변경할 수 있기 때문입니다. 따라서 StringBuilder는 문자열을 추가하거나 변경할 때, 새로운 객체를 생성하지 않고도 내용의 수정이 가능합니다.

해당 질문과 가장 유사한 내용을 담고 있는 답변은 다음 링크에서 확인할 수 있습니다.
- String이 불변 객체인 이유 질문에서 String의 불변성에 대해 자세히 설명하고 있으며, final의 의미와 사용 방법에 대해서도 언급합니다.

이 답변이 인프린님의 궁금증을 해소하는 데 도움이 되었으면 좋겠습니다. 이 내용을 바탕으로 String과 StringBuilder의 차이점을 좀 더 명확하게 이해하실 수 있길 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

인프린님의 프로필 이미지
인프린
질문자

2024. 06. 10. 18:34

String이 불변객체인 이유는 문자열의 내용을 담는 value 필드가 final이기 때문에 새로운 참조값을 할당을 못하니 새롭게 객체를 생성해서 불변객체라고 하는 것인데, 제가 이해가 안가는건 private final byte[] value <- 문자열을 담는 필드
이 필드가 참조 변수 이기 때문에 참조하고 있는 메모리 공간의 주소만 변하지 않으면 안의 내용물은 변해도 상관 없지 않을까 하는 점입니다.

예를 들어 우리가 int[] arr = {1, 2, 3, ,4} 할 때 4를 5로 바꾸어도 arr의 참조값은 변함이 없는데 value도 변수 타입이 기본형이 아닌 참조형이니 final 이어도 참조값이 그대로라면 안의 내용물은 바뀌어도 상관 없을 거 같은데 답변 부탁드립니다.