| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- springboot
- Transaction
- Hexagonal
- 실무
- JPA
- Spring Data JPA
- transactional
- JDBC
- hexagonal architecture
- Layered Architecture
- Spring
- simplejpaRepository
- Adapter
- Today
- Total
Ezcho
[java] String과 StringBuffer 본문
우리는 Java 프로그래밍에서 문자열을 정의할 때 String을 사용한다. 그리고 문자열의 연산이 길어지거나, 문자열을 추가하는 상황에서는 StringBuffer 나 StringBuilder를 사용 해 왔다. 두개의 차이점을 무엇일까?
String
String 은 불변객체이다. String 생성시 할당 된 메모리는 변하지 않는다.
StringBuilder와 StringBuffer는 가변객체이다. 그래서 String 과는 다르게 객체의 공간이 부족해지면 Buffer의 크기를 늘려준다.
String의 불변성
그런데 우리는 String으로 수많은 연산을 한다. 대표적으론 문자열 더하기가 있다.
문자열을더할때 String 내부에서 어떤 변화가 나타나는지 살펴보자
아래 코드를 보자.
String str1 = "hello";
String str2 = " world";
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
str1 = str1 + str2;
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
우선 String의 덧셈이다. str1과 str2를 더한 후 각각 주솟값과 비례된 정숫값(hashCode)을 리턴했다. 결과는 다음과 같다.
99162322
1029451634
1794106052
1029451634
str1은 str1 + str2 연산을 통해 str1에 str2가 단순히 추가되었다고 생각할 수 있다.
하지만 내부적으로 String의 불변성 때문에, str1문자열을 새로운 메모리에 새로운 공간을 할당하여 새롭게 정의되었다.
String 클래스의 문제점
String str3 = str1 + str2;
System.out.println(str3);
위의 코드에서 str1 과 str2를 가져와 새로운 문자열 str3를 만들었다.
우선 String은 기본타입이 아니다.(int, char, double, float...) boolean 을 제외한 나머지 기본형들은 연산자를 사용할 수 있다.
그런데 어떻게 String이 연산자를 사용할 수 있는걸까?
사실 String의 연산에는 숨겨진 비밀이 있다.
본론으로 들어가면
String str3 = str1 + str2;
String str3 = new StringBuffer().append(str1).append(str2).toString();
두 식은 같다!
String은 참조형이라 직접적인 연산이 불가능하다.
String의 덧셈 연산시 StringBuffer를 불러와 append()로 추가, toString()메서드를 통해 반환하여 str3을 초기화 시키는 방식이다.
결국 String str3 = str1 + str2; 는 보기에만 저렇다.
int c = a + b; 같은 연산이랑은 메커니즘 자체가 다른것이다.
그렇다면 StringBuffer에 대해서 조금 더 자세히 알아보자.
StringBuffer
Buffer, 말 그대로 가변성을 띤다. 데이터를 A 에서 B로 옮기는 동안 일시적으로 값을 보관하는 메모리 역할이다.
그럼 StringBuffer는 String을 일시적으로 저장해주는 메모리, 정도로 해석할 수 있다.
String과 다르게 메모리를 새로 할당하지 않는다!
StringBuilder sb = new StringBuilder().append("abc");
System.out.println(sb.hashCode());
sb.append("cde");
System.out.println(sb.hashCode());
796533847
796533847
우리가 흔히 쓰는 StringBuffer의 메서드는 append(), toString() 등이 있다.
StringBuffer sb = new StringBuffer();
로 선언했다고 가정하자 주요 메서드들을 살펴보자
우선 String에서 사용하던 주요 메서드들을 사용할 수 있다.
sb.charAt()
sb.indexOf()
sb.toString()
sb.length()
등등..
sb.append() - 문자열 추가
sb.capacity() - 현재 가진 사이즈 반환 ( length() 와는 다르다)
sb.delete(index1, index2)- index1 ~. index2까지 제거
sb.insert(index, String) - index위치에 문자열 삽입
StringBuffer의 메서드체이닝
StringBuffer 가 갖고있는 메서드들은 대부분 자기 자신을 반환한다. 이것을 메서드 체이닝 이라고 한다.
StringBuffer sb2 = new StringBuffer().append("b").append(true).append(1).append('a').append(0.5);
이런식으로 사용할 수 있다. 이 이유는 append()가 StringBuffer타입을 반환하기 때문이다. 여러 줄로 적을 필요가 없어졌다!
문자열을 정의하기 위해서는
String str4 = new StringBuffer().append("hello").append(" ").append("world").toString();
이렇게 끝만 toString()으로 반환형을 String으로 해 주면 가능하다.
정리
이렇게 String과 StringBuffer를 비교 해 보았다.
String과 StringBuffer는 둘다 char형 배열 (char[])로 이루어져 있지만 메모리의 크기가 불변, 가변에 따라서 나뉜다.
String은 주로 고정되고 정적인 문자열을 정의할 때 사용하면 좋고
StringBuffer는 문자열의 삽입과, 삭제가 잦은 경우에 사용하면 좋다.
String의 경우 생성에 필요한 메모리도 상대적으로 적고, 생성 시간도 오래 걸리지 않는다.
StringBuffer의 경우 생성에 필요한 메모리도 상대적으로 많고, 생성 시간도 걸리는 편이다.
하지만 String의 경우 문자열의 삽입, 삭제가 필요할 때 StringBuffer를 불러와야하는 단점이 있다.
그래서..
생각하면서 맞는 타입을 사용 할 필요가 있다.
'Java' 카테고리의 다른 글
| [java] Date, Calendar클래스, Time 패키지 (0) | 2022.11.09 |
|---|---|
| [java] java.util패키지 (0) | 2022.11.02 |
| [java] Math Class (0) | 2022.10.12 |
| [java] java.lang 패키지 (2) | 2022.10.05 |
| [java]Object 와 오버라이딩 (0) | 2022.09.28 |