JAVA, 문자열 처리

Fillip·2024년 8월 13일
post-thumbnail

문자열이란?

아~ String 자료형?

문자열은 자료형 중 하나라고 봐도 무방하다...라고 하기에는 다른 자료형에 비해 다양한 특성을 가진다.

처음 JAVA 개발 공부를 접할 때 막연히 int, double, long은 숫자 char, String은 문자고 같은 카테고리에서는 크기(범주)적 차이가 있다 라고만 넘어가면 후에 개발 공부를 이어가면서 자신이 만든 함정에 빠질 수 있다.

따라서 구멍없는 개발자 공부의 첫 글은 문자열에 관한 고찰로 다뤄보기로 했다.

그래서 문자열이 뭔데?

문자열은 말그대로 문자(char)형의 배열이다. 따라서 다른 자료형과 다르게 크기적 요소만이 있는 것이 아니라 index(인덱스)요소가 포함되는 자료형이다.

다음 예시를 보면 조금 더 명시적으로 이해할 수 있다.

String str = "star";

위 사진은 코드를 구조화한 것이다. 다른 자료형과는 다르게 자료에 index가 끼어드는 것을 볼 수 있다. 사실 이 구조는 char형 배열을 만들었다고 보아도 무관하다.

String 객체

일반적으로 다른 자료형은 Stack 구조에 자료가 저장되는데 반해 String 자료형은 Stack과 Heap 구조에 생성되고 다뤄진다.

int i = 0;
String str = "star";

메모리 구조

컴퓨터 구조상으로는 위 사진과 같다. 이와 같은 구조를 참조형 변수 라고 한다.
참조형 변수는 값에 주소를 저장해 호출 시 주소 ( Heap 영역 ) 에 들어있는 데이터를 불러오는 변수를 뜻한다.

메모리 영역이 이해가 안가면 아래 링크를 참고하면 좋다.

참고 - 자바 메모리 영역

자바에서 String형은 불변이라는 특징을 가진다. String 객체의 값을 변경할 수 없다는 내용이다.

String str = "Hello";
str = str + " World";

System.out.println(str); // Hello World

위 코드에서 결과를 보면 String 객체 str의 값이 변경된 것으로 보이지만 사실은 아래 그림과 같은 구조로 값이 아니라 Heap 영역에 새로운 주소값으로 데이터가 생성된 것이다.
메모리 구조
직접 확인해보고 싶으면 HashCode() 메소드를 이용해서 주소를 확인해보면된다.

System.out.println(str.HashCode());

불변으로 굳이...?

굳이굳이 불변으로 만든 이유는 3 가지 이유가 있다.

첫번째는 JVM(자바 가싱 머신) 에서는 따로 String Constant Pool 이라는 독립적인 영역을 만들고 문자열들을 Constant 화 하여 다른 변수 혹은 객체들과 공유하게 되는데, 이 과정에서 데이터 캐싱이 일어나고 그 만큼 성능적 이득을 취할 수 있기 때문이다.

말이 조금 이해가 안갈 수 있는데 한마디로 데이터 공유창고인 String Constant Pool이라는 메모리 구조를 자바가 제공한다. 여기서 문자열들을 상수화해서 공유하는데, 데이터를 참조하고 검색해서 이용하는 캐싱 행위가 일어나서 그 만큼 메모리의 성능적 이득을 취할 수 있다는 내용이다.

두번째는 데이터가 불변(immutable) 하다면 Multi-Thread 환경에서 동기화 문제가 발생하지 않기 때문에 더욱 safe 한 결과를 낼 수 있기 때문이다.

이는 멀티쓰레드 환경에서 변하지 않는 데이터 값은 동기화 처리중 충돌될 일이 없기 때문에 안전한 결과를 낼 수 있다는 뜻이다.

세번째는 보안(Security) 적인 측면을 들 수 있다.
예를 들어 데이터베이스 사용자 이름, 암호는 데이터베이스 연결을 수신하기 위해 문자열로 전달되는데, 만일 번지수의 문자열 값이 변경이 가능하다면 해커가 참조 값을 변경하여 애플리케이션에 보안 문제를 일으킬 수 있다.


String Constant Pool이란?

위 자바에서 String형의 불변성을 이용하는 이유에 대해 조금 더 명확하게 이해하기 위해서 설명이 필요할것 같아 집고 넘어가려고한다.

String Constant Pool이라는 독립적인 영역을 만들고 String 자료형을 Constant화 한다고 설명했지만 이해하기에 글보다는 그림을 참고하는 편이 좋다.

String 객체로 생성하게 되면 불필요한 메모리 누수가 발생하기 때문에 리터럴로 선언해서 사용하는 편이 좋다.

명확한 방식은 아래 육하원칙으로 생각하면 이해가 편하다.

누가?   자바 JVM이
언제?   String 자료형을 객체가 아닌 리터럴로 선언했을 때
무엇을?  String 자료형의 값을
어디서?  String Constant Pool에서
어떻게?  리터럴로 선언한 String 값을 String Constant Pool에 중복이 없도록     저장한다.
왜?    캐싱을 유도해서 메모리의 낭비를 줄이기 위해서


참고 - 문자열 처리

궁금하신 부분이나 이상한 부분 언제든 댓글 남겨주세요! 저도 확인해보고 공부해보고 내용 더 추가하도록 하겠습니다! ㅎㅎ

profile
구멍없는 개발자 공부.

0개의 댓글