String 은 Immutable Class 이다

구창회·2022년 10월 17일
0

자바 공부 중

목록 보기
1/10

첫 벨로그

벨로그라는 좋은 기록저장소를 이제야 쓰기 시작하네요 꾸준하게 공부하고 기록하겠습니다.

저는 제로베이스 백엔드 스쿨을 다니며 공부하고 있습니다. 이제 자바 공부한지 2주가 지났고 3주째가 시작이 되네요.

자바를 처음 배워보는데 배울 수록 알아야 하는 것이 많다는 느낌만 듭니다 ㅎㅎ

역시 백엔드 지망생 자바 초보가 배우고 익혀야하는 지식은 너무나 많구나 .. (마크다운 작성도 너무 어색해)

Immutable 클래스?

공부를 하다 JVM 의 스택과 힙의 개념을 알게 되고, 기본형 자료는 스택에, 참조형 객체는 힙에 저장이 되어 스택에서 참조를 한다는 것을 알게 되었다.

그 과정에서 배운 코드 작동 방식이 String 과 같은 불변형(Immutabla class)클래스는 객체가 한번 값이 초기화되면, 변경할 수 없다는 것이다. 그리고 값이 변경될 때에는 내부적으로 동작하여 새로운 String 객체를 내보낸다는 것이다. 아래참조

public class Main {
    public static void main(String[] args) {
        String a = "hello";
        ChangeString(a);
        System.out.println("a = " + a);
    }
    public void ChangeString(String s){
        s += " world";
    }
}

처음 위의 코드를 보았을 때는 당연히 "hello world" 가 출력될 줄 알았는데, 단지 "hello" 만 출력 될 뿐이었다.

Immutable Class 의 객체는 값이 변하지 않고, 새로운 객체를 생성해서 반환한다

위의 문장이 핵심인데 조금 더 자세히 이야기 설명해보자면
스택에 a 라는 변수가 저장되 있고 이는 힙 내부의 String 클래스의 "hello" 값이 저장된 메모리 주소를 가르키고(참조)있다.
그리고 ChangeString 메소드가 불려졌을 때, a 를 인자로 넘겼기 때문에
스택에 s 라는 변수가 저장이 되며 이는 스택의 a 라는 참조형 변수가 가르키는 메모리 주소를 그대로 참조한다.
하지만, 곧 s 가 가르키는 String 의 값에 "world"를 덧붙이려는 시도가 일어났으며 값을 변경할 수 없는 String 클래스이기 때문에 내부적으로 "hello world" 라는 새로운 값을 담은 객체의 주소를 s 가 가르키게 된다.
여기서 a 와 s 가 heap 내부에서 참조하는 메모리 주소가 달라지게 된다.
그리고 scope 개념에 따라 ChangeString 메소드의 중괄호가 닫히면서 s 라는 참조변수는 스택에서 사라지게 되고, s 가 가르키던 heap 내부의 객체는 unreachable 상태가 되어 가비지 컬렉터에 의해 mark 를 받지 못하고 sweep 당하게 된다.

위의 코드 작동 방식을 공부하려다, JVM 의 구조를 다시 공부했으며 가비지컬렉터의 작동방식, 스코프개념도 다시 공부하게 되었다. Immutable 클래스들은 뭐가 다른지 알아보려다 클래스 내부까지 살펴보며 공부하게 되었다. 자바공부는 원래 이렇게 빡센것인가?

반대로 말하면 Immutable class 가 아닌 객체라면 값이 변할 수 있다는 것인데 이것도 테스트를 해보았다.
값이 변할 수 있는 객체로 String 과 비교되는 StringBuffer 나 StringBuilder 를 떠올릴 수 있다.

StringBuffer 로 테스트 해본결과 hello world! 로 잘 값이 변경되어 출력 되는 것을 알 수 있다.
내부 코드를 살펴보면 this 를 리턴하기 때문인데, 이에 대한 공부를 더 해서 뒤에서 글을 작성할 예정이다.

String 클래스 들여다 보기

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

String 클래스의 내부를 들여다보면, 생성자에 쓰이는 value[]가 final 선언이 되어있는 것을 볼 수 있다. 변수에 final 이 붙으면 한번 값이 초기화 되면 절대 변경 불가능 하다는 것을 말한다. 다른 Immutable 클래스들의 내부를 들여다 보면 생성에 쓰이는 변수들이 전부 final 선언이 되어 있는 것을 볼 수 있다.

profile
백엔드 엔지니어 프로 지망생

0개의 댓글