Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 야학
- 생활코딩 머신러닝야학
- pandas
- flatten
- reshape
- 생활코딩 데이터베이스
- 카카오클라우드스쿨2기
- 이것이 자바다
- 연산자
- tensorflow
- 파이썬
- 개발자
- 생활코딩
- 데이터베이스
- Database
- Java
- 머신러닝(딥러닝)
- 머신러닝야학
- JavaScript
- 판다스
- Python
- 머신러닝
- MySQL
- 데이터베이서
- CNN
- 딥러닝
- 데이터베이스 개론
- LeNet
Archives
- Today
- Total
IT's 우
[Java]문자열 클래스 본문
728x90
[JAVA] 문자열 클래스
1. String 특징
- new 연산을 통해 생성된 인스턴스의 메모리 공간은 변하지 않음(Immutable) -> 힙 메모리(Heap)
- Garbage Collector로 제거되어야 함
- 문자열 연산 시 새로 객체를 만드는 Overhead 발생
- 객체가 불변하므로, Multihead에서 동기화를 신경 쓸 필요 X(조회 연산에 매우 큰 장점)
- 내부 데이터를 자유롭게 공유 가능
String name = "woo";
// 가비지
name = "jiwoo";
name = new String("woo");
- 이것은 name이 처음에 참조하고 있는 "woo"가 "jiwoo"로 변경되는 것이 아니라 "jiwoo"라는 새로운 객체를 만들고(오버헤드 발생) 그 객체를 name이 참조하게 하는 것.
- new 키워드를 한 번 더 사용하게 되면 같은 "woo" 값이지만 다른 메모리 공간(Heap 영역 안)을 참조
- 이때 "woo"라고 생성된 String 객체는 더 이상 참조를 하지 않고 사용이 되지 않아서 Garbage(가비지)가 되었다. 이러한 메모리 누수를 방지하기 위해 가비지 컬렉터(Garbage Collectorm GC)가 주기적으로 검사하여 메모리를 청소해 준다.
- 사용하는 경우: 문자열 연산이 적고 멀티스레드 환경일 경우
2. StringBuffer, StringBuilder 특징
- 공통점
- new 연산으로 클래스를 한 번만 만듦(Mutable)
- 문자열 연산 시 새로 객체를 만들지 않고, 크기를 변경시킴
- 가변성(Mutable)
- 문자열 연산 등으로 기존 객체의 공간이 부족하게 되는 경우 기존의 버퍼 크기를 늘리며 유연하게 동작.
- StringBuffer와 StringBuilder 클래스의 메서드가 동일
- .append(), .delete() 등의 API를 이용하여 동일 객체 내에서 문자열을 변경하는 것이 가능
- 단점: 초기 버퍼의 크기 설정, 버퍼 크기 줄이고 늘리며 객체 생성 속도가 느리다.
- 차이점
- StringBuffer는 Thread-Safe 함 / StringBuilder는 Thread-safe 하지 않음(불가능)
- StringBuffer
- 동기화 키워드(synchronized keyword)를 지원하여 멀티스레드 환경에서 안전하다.
- 사용하는 경우: 사용하는 경우: 문자열의 추가, 수정, 삭제가 빈번하게 발생할 경우, 멀티 스레드 환경
- StringBuilder
- 동기화를 지원하지 않지만 단일스레드에서의 성능은 StringBuffer보다 뛰어나다
- 사용하는 경우: 문자열 연산이 많고 단일스레드이거나 동기화를 고려하지 않아도 되는 경우
[불변 객체 참고]
불변 객체(Immutable Object)란?
- 불변 객체란 객체 생성 이후 내부의 상태가 변하지 않는 객체이다. 불변 객체는 read-only 메소드만 제공하며, 객체의 내부 상태를 제공하지 않는 메소드를 제공하지 않거나 방어적 복사(defensive-copy)를 통해 제공한다.
- 불변객체는 재할당은 가능하지만, 한번 할당하면 내부 데이터를 변경할 수 없는 객체
- 즉, 객체의 값을 할당하면 내부 데이터를 변경시킬 수 없다는 것. Ex) String, Integer, Boolean
- 이것은 str이 처음에 참조하고 있는 "a" 값이 "b"로 변경되는 것이 아니라 "ab"라는 새로운 객체를 만들고 그 객체를 str이 참조하게 하는 것
- String str = "a";
str = "ab"
- 즉, 객체의 값을 할당하면 내부 데이터를 변경시킬 수 없다는 것. Ex) String, Integer, Boolean
String은 불변 클래스
- String 내부의 char형 배열을 얻어 수정하여도 반영 X
- 방어적 복사(defensive-copy), String의 toCharArray
- Java에서는 배열이나 객체 등의 참조(Reference)를 전달한다. 참조를 통해 값을 수정하면 내부의 상태가 변하기 때문에 내부를 복사하여 전달하고 있는데, 이를 방적 복사(defensive-copy)라고 한다.
public char[] toCharArray() { // Cannot use Arrays.copyOf because of class initialization order issues char result[] = new char[value.length]; System.arraycopy(value, 0, result, 0, value.length); return result; }
불변 객체(Immutable Object) 및 final을 사용해야 하는 이유
- Thread-Safe 하여 병렬 프로그래밍에 유용하며, 동기화를 고려하지 않아도 됨.
- 멀티 스레드 환경에서 동기화 문제가 발생하는 이유는 공유 자원에 동시에 쓰기(Write) 때문. 하지만 만약 공유 자원이 불변이라면 더 이상 동기화를 고려하지 않아도 될 것. 왜냐하면 항상 동일한 값을 반환할 것이기 때문. 이는 안정성을 보장할 뿐만 아니라 동기화를 하지 않음으로써 이점도 가져다 줌.
- 실패 원자적인(Failure Atomic) 메소드를 만들 수 있음.
- 가변 객체를 통해 작업을 하는 도중 예외가 발생하면 해당 객체가 불안정한 상태에 빠질 수 있고, 불안정한 생태를 갖는 객체는 또 다른 에러를 유발할 수 있음. 하지만 불변 객체라면 예외가 발생하여도 메소드 호출 전의 상태를 유지할 수 있을 것. 그리고 예외가 발생하여도 오류가 발생하지 않은 것처럼 다음 로직을 처리할 수 있음.
- Cache나 Map 또는 Set 등의 요소로 활용하기에 더욱 적합
- 만약 캐시나 Map, Set 등의 원소인 가변 객체가 변경되었다면 이를 갱신하는 등의 부가 작업이 필요할 것. 하지만 불변 객체라면 한 번 데이터가 저장된 이후에 다른 작업들은 고려하지 않아도 되므로 사용하는데 용이하게 작용할 것.
- 부수 효과(Side Effect)를 피해 오류 가능성을 최소화할 수 있음
- 부수 효과란 변수의 값이나 상태 등의 변화가 발생하는 효과를 의미. 만약 객체의 수정자(Setter)를 통해 여러 객체들에서 값을 변경한다면 객체의 상태를 예측하기 어려워질 것. 바뀐 상태를 파악하기 위해서는 메서드들을 살펴보아야 하고, 이는 유지보수성을 상당히 떨어뜨림. 그래서 이러한 부수효과가 없는 순수 함수들을 만드는 것이 상당히 중요. 불변 객체는 기본적으로 값의 수정이 불가능하기 때문에 변경 가능성이 적으며, 객체의 생성과 사용이 상당히 제한됨. 그렇기 때문에 메소드들은 자연스럽게 순수 함수들로 구성될 것이고, 다른 메소드가 호출되어도 객체의 상태가 유지되기 때문에 안전하게 객체를 다시 사용할 수 있음. 이러한 불변 객체는 유지보수성이 높은 코드를 작성하도록 도와줄 것.
- 다른 사람이 작성한 함수를 예측가능하며 안전하게 사용할 수 있다.
- 일반적으로 개발은 다른 사람과 협업함. 불변성(Immutability)은 협업 과정에서도 도움을 주는데, 불변성이 보장된 함수라면 다른 사람이 개발한 함수를 위험 없이 이용할 수 있다. 마찬가지로 다른 사람도 내가 작성한 메서드를 호출하여도, 값이 변하지 않음을 보장받을 수 있다. 그렇기에 우리는 변경에 대한 불안 없이 다른 사람의 코드를 이용할 수 있다. 또한 불필요한 시간을 절약할 수 있다.
- 가비지 컬렉션의 성능을 높일 수 있다.
- 불변성(Immutability)의 많은 이점 중에서 많은 사람들이 놓치는 것이 바로 GC의 성능을 높여준다는 것이다. 불변의 객체는 한 번 생성된 이후에 수정이 불가능한 객체로, Java에서는 final 키워드를 사용하여 불변의 객체를 생성할 수 있다. 이렇게 객체를 생성하기 위해서는 객체를 가지는 또 다른 컨테이너 객체(ImmutableHolder)도 존재한다는 것인데, 당연히 불변의 객체(Object value)가 먼저 생성되어야 컨테이너 객체가 이를 참조할 수 있을 것이다. 즉, 컨테이너는 컨테이너가 참조하는 가장 젊은 객체들보다 더 젊다는 것(늦게 생성되었다는 것)이다.
- Object 타입의 value 객체 생성
- ImmutableHolder 타입의 컨테이너 객체 생성
- ImmutableHolder가 value 객체를 참조
- 불변성(Immutability)의 많은 이점 중에서 많은 사람들이 놓치는 것이 바로 GC의 성능을 높여준다는 것이다. 불변의 객체는 한 번 생성된 이후에 수정이 불가능한 객체로, Java에서는 final 키워드를 사용하여 불변의 객체를 생성할 수 있다. 이렇게 객체를 생성하기 위해서는 객체를 가지는 또 다른 컨테이너 객체(ImmutableHolder)도 존재한다는 것인데, 당연히 불변의 객체(Object value)가 먼저 생성되어야 컨테이너 객체가 이를 참조할 수 있을 것이다. 즉, 컨테이너는 컨테이너가 참조하는 가장 젊은 객체들보다 더 젊다는 것(늦게 생성되었다는 것)이다.
[Garbage Collection(가비지 컬렉션) 참고]
1. Garbage Collection(가비지 컬렉션)이란?
- 프로그램을 개발하다 보면 유효하지 않은 메모리인 가비지(Garbage)가 발생하게 된다. C언어를 이용하면 free()라는 함수를 통해 직접 메모리를 해제해주어야 한다. 하지만 Java나 Kotlin을 이용해 개발을 하다 보면 개발자가 메모리를 직접 해제해 주는 일이 없다. 그 이유는 JVM의 가비지 컬렉터가 불필요한 메모리를 알아서 정리해 주기 때문이다. 대신 Java에서 명시적으로 불필요한 데이터를 표현하기 위해서 일반적으로 null을 선언해 준다.
Person person = new Person();
person.setName("Woo");
person = null;
// 가비지 발생
person = new Person();
person.setName("Jiwoo");
- 기존의 Mang으로 생성된 person 객체는 더 이상 참조를 하지 않고 사용이 되지 않아서 Garbage(가비지)가 되었다. Java나 Kotlin에서는 이러한 메모리 누수를 방지하기 위해 가비지 컬렉터(Garbage Collectorm GC)가 주기적으로 검사하여 메모리를 청소해 준다.
- 물론 Java에서도 System.gc()를 이용해 호출할 수 있지만, 해당 메서드를 호출하는 것은 시스템의 성능에 매우 큰 영향을 미치므로 절대 호출해서는 안된다.
참고자료
- https://mangkyu.tistory.com/131
- https://gyoogle.dev/blog/computer-language/Java/String%20&%20StringBuilder%20&%20StringBuffer.html
- https://velog.io/@conatuseus/Java-Immutable-Object%EB%B6%88%EB%B3%80%EA%B0%9D%EC%B2%B4
- https://mangkyu.tistory.com/118
- https://velog.io/@0sunset0/StringStringBuilderStringBuffer-%EC%B0%A8%EC%9D%B4-thread-safe%EB%9E%80-String%EC%9D%B4-%EB%B6%88%EB%B3%80%EA%B0%9D%EC%B2%B4%EC%9D%B8-%EC%9D%B4%EC%9C%A0
- https://ifuwanna.tistory.com/221
- https://velog.io/@heoseungyeon/StringBuilder%EC%99%80-StringBuffer%EB%8A%94-%EB%AC%B4%EC%8A%A8-%EC%B0%A8%EC%9D%B4%EA%B0%80-%EC%9E%88%EB%8A%94%EA%B0%80
728x90
반응형
'CS > Java' 카테고리의 다른 글
[java] 추상 클래스와 인터페이스 차이 (0) | 2023.07.14 |
---|---|
[java] final vs finally vs finalize (0) | 2023.06.30 |
[Java] == 와 equals 차이 (1) | 2023.06.15 |
[Java] String vs Char 차이 (1) | 2023.06.15 |
[Java] Object 클래스 (0) | 2023.06.01 |