"김영한의 실전 자바 - 중급편" 내용을 참고하여 정리함.
목차
1. String 클래스 - 기본
자바에서 문자열을 다루는 방법
자바에서 문자를 다루는 대표적인 타입은 2가지가 있다.
- `char` : 하나의 문자만 저장 가능
- `String` : 여러 개의 문자를 저장하고 다룰 수 있는 클래스
char[] charArr = new char[]{'h', 'e', 'l', 'l', 'o'};
System.out.println(charArr); // hello
String str = "hello";
System.out.println("str = " + str); // str = hello
`char[]`로 여러 문자를 다루기 불편하기 때문에 자바는 문자열을 편리하게 다룰 수 있는 `String` 클래스를 제공한다.
String 객체 생성 방법
1. 문자열 리터럴 사용
String str1 = "hello";
- 문자열 상수 풀(String Constant Pool)에 저장됨.
- 같은 문자열 리터럴을 재사용하여 메모리 절약 가능.
2. new 키워드를 이용한 객체 생성
String str2 = new String("hello");
- Heap 메모리에 새로운 `String` 객체가 생성됨.
- 같은 문자열이라도 새로운 객체를 생성하므로 `==` 비교 시 `false`.
String 클래스의 구조
public final class String {
// 문자열 보관 (속성(필드))
private final char[] value; // Java 9 이전
private final byte[] value; // Java 9 이후
//여러 메서드 (기능)
public String concat(String str) {...}
public int length() {...}
...
}
- String은 불변(Immutable) 객체이므로 `final` 로 선언된 배열을 내부에서 관리한다.
- 문자 데이터 자체는 `char[]`에 보관된다.
- 개발자가 직접 다루기 불편한 `char[]`을 내부에 감추고, `String` 클래스를 사용하는 개발자가 편 리하게 문자열을 다룰 수 있도록 다양한 기능을 제공한다.
참고: Java 9 이후
`char[]` 대신 `byte[]` 을 사용한다.
단순 영어, 숫자로만 표현된 경우 1byte 를 사용하고(정확히는 Latin-1 인코딩의 경우 1byte 사용) , 그렇지 않은 나머지의 경우 2byte 인 UTF-16 인코딩을 사용한다. 따라서 메모리를 더 효율적으로 사용할 수 있게 변경되었다.
String 클래스와 참조형
String a = "hello"; // x001
String b = "java"; // x002
String result1 = a.concat(b);
String result2 = a + b; // 원칙적으로 참조값끼리 더할 수 없지만 편의상 제공함
System.out.println("result1 = " + result1); // result1 = hello java
System.out.println("result2 = " + result2); // result2 = hello java
- `String` 은 클래스이다. `int` , `boolean` 같은 기본형이 아니라 참조형이다.
- 참조형은 변수에 `x001`과 같이 계산할 수 없는 참조값이 들어있기 때문에 원칙적으로 `+` 같은 연산을 사용할 수 없다.
- 문자열은 자주 다루어지기 때문에 자바 언어에서 편의상 `+` 연산을 제공한다.
2. String 클래스 - 비교
== vs equals() 차이
- `==` 연산자: 참조값(주소값) 비교 → 두 변수가 같은 객체를 가리키는지 확인한다. => 동일성(Identity)
- `equals()` 메서드: 내용(문자열 값) 비교 → 문자열 값이 같은지를 확인한다. => 동등성(Equality)
new String("hello") 사용 시
- `new String("hello")` 는 Heap 메모리에 새로운 String 객체를 생성한다.
- 문자열 상수 풀을 사용하지 않기 때문에, 동일한 문자열이라도 새로운 객체가 만들어진다.
- `str1` 과 `str2` 는 서로 다른 인스턴스이므로 동일성 (`==`) 비교에 실패한다.
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // false (다른 객체(인스턴스))
System.out.println(str1.equals(str2)); // true (같은 문자열 내용)

- `str1` 과 `str2` 는 Heap 메모리에 각각 다른 객체로 생성됨,
- 따라서 `==` 비교는 `false`, 하지만 `equals()` 비교는 `true`.
문자열 리터럴과 String Constant Pool
- 문자열 리터럴("hello")을 사용하면, 문자열 상수 풀(String Constant Pool)에 저장된다.
- 같은 문자열이 이미 존재하면, 기존 문자열을 재사용하고 새로운 객체를 만들지 않는다.
String str3 = "hello";
String str4 = "hello";
System.out.println(str3 == str4); // true (같은 리터럴, 같은 객체)
System.out.println(str3.equals(str4)); // true
- `str3` 과 `str4` 는 같은 `"hello"` 객체를 참조하므로 `==` 비교도 `true` 가 됨.
- 문자열이 변하지 않으므로 메모리 절약 효과가 있음.
참고: 풀(Pool)
- Pool(풀)은 공용 자원을 미리 만들어두고 여러 곳에서 재사용하는 공간이다.
- 문자열 풀(String Constant Pool)은 Heap 영역에서 문자열 리터럴을 효율적으로 관리한다.
- 해시(Hash) 알고리즘을 사용하여 빠르게 문자열을 검색할 수 있도록 최적화된다.
항상 equals()를 사용해야 하는 이유
public static void main(String[] args) {
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("메서드 호출 비교1: " + isSame(str1, str2));
String str3 = "hello";
String str4 = "hello";
System.out.println("메서드 호출 비교2: " + isSame(str3, str4));
}
private static boolean isSame(String x, String y) {
// return x == y; // (X)
return x.equals(y); // (O) 문자열 비교는 항상 동등성 비교를 해야함
}
- `isSame(String x, String y)` 같은 메서드에서 `==` 을 사용하면 의도하지 않은 결과 발생 가능하다.
- `new String("hello")`는 Heap 메모리에 새로운 객체를 생성하므로 `==` 비교 시 `false`가 된다.
반면 `"hello"` 리터럴은 String Constant Pool에서 재사용되므로 `==` 비교 시 `true`가 나온다. - 따라서 항상 `equals()`를 사용해야 한다.
3. String 클래스 - 불변 객체
String이 불변(Immutable)한 이유
- `String` 은 한 번 생성되면 변경할 수 없는 불변 객체이다.
- 새로운 값으로 변경하면 기존 객체를 수정하는 것이 아니라, 새로운 객체를 생성한다.
String str = "hello";
str.concat(" java");
System.out.println(str); // "hello" (변경되지 않음)
→ str.concat(" java")가 실행되었지만 기존 문자열은 변경되지 않음.
새로운 객체 반환을 확인하는 예제
public String concat(String str) {
if (str.isEmpty()) {
return this;
}
return StringConcatHelper.simpleConcat(this, str);
}
- `String.concat()` 은 내부에서 새로운 `String` 객체를 만들어서 반환한다.
String str1 = "hello";
String str2 = str1.concat(" java");
System.out.println(str1); // "hello" (변경되지 않음)
System.out.println(str2); // "hello java" (새로운 객체)

- "hello"는 변하지 않고, "hello java"라는 새로운 객체가 생성된다. → 불변과 기존 객체의 값을 유지함
String이 불변으로 설계된 이유
- 문자열 풀 최적화 → 불변성이 없으면 문자열 공유 시 사이드 이펙트 발생 가능
- 쓰레드 안전성 → 변경되지 않으므로 여러 쓰레드에서 안전하게 공유 가능
- 보안 강화 → 중요한 데이터(URL, 비밀번호 등)의 조작 위험 방지
- 해시코드 캐싱 → HashMap, HashSet에서 빠른 검색 가능
4. String 클래스 - 주요 메서드
String 클래스는 문자열을 다루기 위한 다양한 기능을 제공한다.
문자열 정보 조회
메서드 | 설명 |
length() | 문자열의 길이를 반환 |
isEmpty() | 문자열이 비어 있는지 확인 (길이가 0) |
isBlank() | 문자열이 비어 있는지 확인 (길이가 0이거나 공백(Whitespace)만 있는 경우), 자바 11 |
charAt(int index) | 지정된 인덱스에 있는 문자를 반환 |
String str = "Hello, Java!";
System.out.println("문자열의 길이: " + str.length()); // 12
System.out.println("문자열이 비어 있는지: " + str.isEmpty()); // false
System.out.println("문자열이 비어 있거나 공백인지1: " + str.isBlank()); // false
System.out.println("문자열이 비어 있거나 공백인지2: " + " ".isBlank()); // true
char c = str.charAt(7);
System.out.println("7번 인덱스의 문자= " + c); // J
문자열 비교
메서드 | 설명 |
equals(Object anObject) | 두 문자열이 동일한지 비교 |
equalsIgnoreCase(String anotherString) | 두 문자열을 대소문자 구분 없이 비교 |
compareTo(String anotherString) | 두 문자열을 사전 순으로 비교 |
compareToIgnoreCase(String str) | 두 문자열을 대소문자 구분 없이 사전적으로 비교 |
startsWith(String prefix) | 특정 접두사로 시작하는지 확인 |
endsWith(String suffix) | 특정 접미사로 끝나는지 확인 |
String str1 = "Hello, Java!"; // 대문자 일부 있음
String str2 = "hello, java!"; // 대문자 없음 모두 소문자
String str3 = "Hello, World!";
System.out.println("str1 equals str2: " + str1.equals(str2)); // false
System.out.println("str1 equals str2: " + str1.equalsIgnoreCase(str2)); // true
System.out.println("'a' compareTo 'b': " + "a".compareTo("b")); // -1
System.out.println("'b' compareTo 'a': " + "b".compareTo("a")); // 1
System.out.println("'b' compareTo 'a': " + "c".compareTo("a")); // 2
System.out.println("str1 compareTo str3: " + str1.compareTo(str3)); // -13
System.out.println("str1 compareTo str2: " + str1.compareToIgnoreCase(str2)); // 0
System.out.println("str1 starts with 'Hello': " + str1.startsWith("Hello")); // true
System.out.println("str1 ends with 'Hello': " + str1.endsWith("Java!")); // true
문자열 검색
메서드 | 설명 |
contains(CharSequence s) | 특정 문자열을 포함하고 있는지 확인 |
indexOf(String ch) / indexOf(String ch, int fromIndex) |
문자열이 처음 등장하는 위치를 반환 |
lastIndexOf(String ch) | 문자열이 마지막으로 등장하는 위치를 반환 |
String str = "Hello, Java! Welcome to Java world.";
System.out.println("문자열에 'Java'가 포함되어 있는지: " + str.contains("Java")); // true
System.out.println("'Java'의 첫 번째 인덱스: " + str.indexOf("Java")); // 7
System.out.println("인덱스 10부터 'Java'의 인덱스: " + str.indexOf("Java", 10)); // 24
System.out.println("'Java'의 마지막 인덱스: " + str.lastIndexOf("Java")); // 24
문자열 조작 및 변환
String은 불변 객체이기 때문에 반환값을 받아 사용해야 한다.
메서드 | 설명 |
substring(int beginIndex) / substring(int beginIndex, int endIndex) |
문자열의 부분 문자열을 반환 |
concat(String str) | 문자열의 끝에 다른 문자열을 붙임 |
replace(CharSequence target, CharSequence replacement) | 특정 문자열을 새 문자열로 대체 |
replaceAll(String regex, String replacement) | 정규 표현식과 일치하는 부분을 새 문자열로 대체 |
replaceFirst(String regex, String replacement) | 정규 표현식과 일치하는 첫 번째 부분을 새 문자열로 대체 |
toLowerCase() / toUpperCase() | 소문자나 대문자로 변환 |
trim() | 문자열 양쪽 끝의 공백을 제거 (단순 공백만 제거) |
strip() | 공백과 유니코드 공백을 포함해서 제거 (자바 11) |
String str = "Hello, Java! Welcome to Java";
System.out.println("인덱스 7부터 부분 문자열: " + str.substring(7)); // Java! Welcome to Java
System.out.println("인덱스 7부터 12까지의 부분 문자열: " + str.substring(7, 12)); // Java!
System.out.println("문자열 결합: " + str.concat("!!!")); // + 와 같음 // Hello, Java! Welcome to Java!!!
System.out.println("'Java'를 'World'로 대체: " + str.replace("Java", "World")); // Hello, World! Welcome to World
System.out.println("첫 번째 'Java'를 'World'로 대체: " + str.replaceFirst("Java", "World")); // Hello, World! Welcome to Java
String strWithSpace = " Java Programming ";
System.out.println("소문자로 변환: " + strWithSpace.toLowerCase());
System.out.println("대문자로 변환: " + strWithSpace.toUpperCase());
System.out.println("공백 제거(trim): '" + strWithSpace.trim() + "'");
System.out.println("공백 제거(trim): '" + strWithSpace.strip() + "'"); // 자바 11
System.out.println("앞 공백 제거(trim): '" + strWithSpace.stripLeading() + "'");
System.out.println("뒤 공백 제거(trim): '" + strWithSpace.stripTrailing() + "'");
소문자로 변환: java programming
대문자로 변환: JAVA PROGRAMMING
공백 제거(trim): 'Java Programming'
공백 제거(trim): 'Java Programming'
앞 공백 제거(trim): 'Java Programming '
뒤 공백 제거(trim): ' Java Programming'
문자열 분할 및 조합
메서드 | 설명 |
split(String regex) | 정규 표현식을 기준으로 분할 |
join(CharSequence delimiter, CharSequence... elements) | 주어진 구분자로 여러 문자열을 결합 |
String str = "Apple,Banana,Orange";
// split()
String[] splitStr = str.split(",");
for (String s : splitStr) {
System.out.println(s);
}
// join()
String joinedStr = String.join("-", "A", "B", "C");
System.out.println("joinedStr = " + joinedStr);
// 문자열 배열 연결
String result = String.join("-", splitStr);
System.out.println("result = " + result);
Apple
Banana
Orange
joinedStr = A-B-C
result = Apple-Banana-Orange
기타 유틸리티
메서드 | 설명 |
valueOf(Object obj) | 다양한 타입을 문자열로 변환 |
toCharArray() | 문자열을 문자 배열로 변환 |
format(String format, Object... args) | 형식 문자열과 인자를 사용하여 새로운 문자열을 생성 |
matches(String regex) | 문자열이 주어진 정규 표현식과 일치하는지 확인 |
int num = 100;
boolean bool = true;
Object obj = new Object();
String str = "Hello, Java!";
// valueOf 메서드 - obj.toString() 을 반환함
String numString = String.valueOf(num);
System.out.println("숫자의 문자열 값: " + numString); // 100
String boolString = String.valueOf(bool);
System.out.println("불리언의 문자열 값: " + boolString); // true
String objString = String.valueOf(obj);
System.out.println("객체의 문자열 값: " + objString); // java.lang.Object@4e50df2e
// 문자 + x -> 문자
String numString2 = "" + num;
System.out.println("빈문자열 + num: " + numString2); // 100
// toCharArray 메서드
char[] strCharArray = str.toCharArray();
System.out.println("문자열을 문자 배열로 반환: " + strCharArray); // + 가 있어서 참조값을 반환 // [C@1d81eb93
for (char c : strCharArray) {
System.out.print(c); // Hello, Java!
}
System.out.println();
int num = 100;
boolean bool = true;
String str = "Hello, Java!";
// format 메서드
String format1 = String.format("num: %d, bool: %b, str: %s", num, bool, str);
System.out.println("format1 = " + format1); // num: 100, bool: true, str: Hello, Java!
String format2 = String.format("숫자: %.2f", 10.1234);
System.out.println("format2 = " + format2); // 숫자: 10.12
// printf
System.out.printf("숫자: %.2f\n", 10.1234); // 10.12
// matches 메서드
String regex = "Hello, (Java!|World)";
System.out.println("'str'이 패턴과 일치하는가? " + str.matches(regex)); // true
format 메서드에서 `%d` 는 숫자, `%b` 는 `boolean` , `%s` 는 문자열을 뜻한다.
참고: CharSequence 는 String , StringBuilder 의 상위 타입이다.
5. StringBuilder - 가변 String
String 클래스의 단점
- String은 불변(Immutable) 객체이므로 문자열이 변경될 때마다 새로운 객체가 생성된다.
- 중간에 만들어진 객체는 GC의 대상이 된다.
- 문자열을 반복해서 더하면 메모리 낭비 및 성능 저하 발생한다.
String str = "";
for (int i = 0; i < 100000; i++) {
str += "Hello"; // 비효율적임. 매번 새로운 String 객체 생성.
}
StringBuilder를 사용한 해결
- StringBuilder는 가변(Mutable) 객체로, 문자열을 변경할 때 새로운 객체를 생성하지 않는다.
- 문자열 추가, 수정, 삭제가 빈번한 경우 성능 최적화에 유리하다.
- 가변의 경우 사이드 이펙트에 주의하여 사용해야 한다.
- StringBuilder는 내부에 `final`이 아닌 변경할 수 있는 `byte[]`를 가지고 있다.
public final class StringBuilder {
char[] value;// 자바 9 이전
byte[] value;// 자바 9 이후
//여러 메서드
public StringBuilder append(String str) {...}
public int length() {...}
...
}
주요 메서드
메서드 | 설명 |
append(String s) | 문자열 추가 |
insert(int index, String s) | 특정 위치에 문자열 삽입 |
delete(int start, int end) | 특정 범위의 문자열 삭제 |
reverse() | 문자열 뒤집기 |
toString() | StringBuilder → String 변환 |
StringBuilder sb = new StringBuilder();
sb.append("A");
sb.append("B");
sb.append("C");
sb.append("D");
System.out.println("sb = " + sb); // ABCD
sb.insert(4, "Java");
System.out.println("insert = " + sb); // ABCDJava
sb.delete(4, 8);
System.out.println("delete = " + sb); // ABCD
sb.reverse(); // 불변 아님
System.out.println("reverse = " + sb); // DCBA
// StringBuilder -> String (불변으로 변경)
String string = sb.toString();
System.out.println("string = " + string);// DCBA
`StringBuilder` 는 보통 문자열을 변경하는 동안만 사용하다가 문자열 변경이 끝나면 안전한(불변) String 으로 변환하는 것이 좋다.
6. String 최적화
자바의 String 최적화
자바는 문자열 최적화를 위해 여러 가지 기법을 자동 적용한다.
대표적인 방법은 문자열 리터럴 최적화와 문자열 변수 최적화가 있다.
1. 문자열 리터럴 최적화
자바 컴파일러는 문자열 리터럴을 자동으로 합쳐서 최적화한다.
즉, 컴파일 단계에서 문자열을 결합하여 런타임에서 불필요한 연산을 방지한다.
컴파일 전
String helloWorld = "Hello, " + "World!";
컴파일 후
String helloWorld = "Hello, World!";
위 최적화를 통해 런타임에서 별도의 문자열 결합 연산 없이 실행할 수 있어 성능이 향상된다.
2. 문자열 변수 최적화
문자열 리터럴과 다르게, 변수에 저장된 문자열을 합칠 때는 최적화가 어렵다.
컴파일러는 변수 내부의 값을 컴파일 시점에 알 수 없기 때문이다.
예제 코드
String result = str1 + str2; // str1과 str2의 값은 실행 시점에 결정됨.
자바는 이런 경우 자동으로 StringBuilder를 사용하여 최적화한다.
(최적화 방식은 자바 버전에 따라 다를 수 있음.)
컴파일 후 변환된 코드
String result = new StringBuilder().append(str1).append(str2).toString();
- 이러한 이유로 단순한 문자열 결합에서는 `StringBuilder`를 사용하지 않아도 된다.
- 즉, `+` 연산자로 문자열을 합쳐도 자바가 알아서 최적화해준다.
참고: 자바 9 이후부터는 `StringConcatFactory` 를 사용해 더욱 최적화된 방식으로 문자열을 처리한다.
String 최적화가 어려운 경우
자바가 자동으로 최적화를 수행해주지만, 반복문 내부에서 문자열을 합치는 경우 최적화가 어렵다.
이유는 반복 횟수와 문자열의 변화를 컴파일러가 예측할 수 없기 때문이다.
1. 반복문 내 문자열 연결 (최적화 어려움)
반복문 안에서 문자열을 계속 추가하면 매번 새로운 String 객체가 생성되므로 성능이 급격히 저하된다.
비효율적인 코드
long startTime = System.currentTimeMillis();
String result = "";
for (int i = 0; i < 100000; i++) {
result += "Hello Java ";
}
long endTime = System.currentTimeMillis();
System.out.println("result = " + result);
System.out.println("time = " + (endTime - startTime) + "ms");
최적화 방식 (자바 버전에 따라 다름)
String result = "";
for (int i = 0; i < 100000; i++) {
result = new StringBuilder().append(result).append("Hello Java ").toString();
}
result = Hello Java Hello Java ....
time = 2490ms
- 반복문 내부에서 문자열을 계속 수정하면 객체가 계속 생성되어 성능이 저하된다.
- 실제로 100,000번 반복하면 약 2.5초가 걸린다.
=> 반복문 내 문자열 연결은 최적화되지 않으므로 `StringBuilder`를 직접 사용해야 한다.
2. StringBuilder를 사용한 최적화
반복문 내에서 문자열을 수정하는 경우 직접 StringBuilder를 사용하면 성능이 크게 개선된다.
최적화 코드
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) {
sb.append("Hello Java ");
}
String result = sb.toString();
long endTime = System.currentTimeMillis();
System.out.println("result = " + result);
System.out.println("time = " + (endTime - startTime) + "ms");
result = Hello Java Hello Java ....
time = 3ms
- `StringBuilder`를 사용하면 문자열을 직접 수정할 수 있어 속도가 향상된다.
- 100,000번 반복 시 기존 코드(2.5초)보다 훨씬 빠른 0.003초로 실행된다.
StringBuilder를 직접 사용해야 하는 경우
- 반복문에서 반복적으로 문자열을 연결할 때
- 조건문을 통해 문자열을 동적으로 조합해야 할 때
- 긴 문자열의 특정 부분을 수정해야 할 때
- 매우 긴 대용량 문자열을 처리할 때
StringBuilder vs StringBuffer
자바에는 StringBuilder와 비슷한 기능을 하는 StringBuffer 클래스가 있다.
두 클래스의 차이점은 멀티쓰레드 환경에서 동기화 지원 여부이다.
StringBuilder | StringBuffer | |
동기화(Synchronization) | 미지원 (싱글 쓰레드에서 빠름) | 지원 (멀티 쓰레드에서 안전) |
성능 | 빠름 (동기화 없음) | 상대적으로 느림 (동기화 오버헤드) |
사용 추천 환경 | 단일 쓰레드 환경에서 성능 최적화 | 멀티 쓰레드 환경에서 안전하게 사용 |
- 즉, StringBuilder는 성능이 좋지만, 멀티쓰레드 환경에서는 StringBuffer를 고려해야 한다.
- 멀티쓰레드 개념이 익숙하지 않다면, StringBuilder를 기본적으로 사용하면 된다.
7. 메서드 체인닝 - Method Chaining
메서드 체이닝이란?
- 메서드 호출의 결과로 자기 자신의 참조값을 반환하여, 연속적으로 메서드를 호출할 수 있도록 하는 기법이다.
- 메서드가 체인(Chain)처럼 연결된 형태로 호출되므로, 코드를 더 간결하고 읽기 쉽게 작성할 수 있다.
- `StringBuilder`, `Stream API`, `Optional API` 등 다양한 라이브러리에서 활용된다.
메서드 체이닝을 적용한 경우
1. `this` 반환을 이용한 체이닝 구현
public class ValueAdder {
private int value;
public ValueAdder add(int addValue) {
value += addValue;
return this; // 자기 자신 반환
}
public int getValue() {
return value;
}
}
2. 체이닝을 활용한 호출 방식
public class MethodChainingMain3 {
public static void main(String[] args) {
ValueAdder adder = new ValueAdder();
int result = adder.add(1).add(2).add(3).getValue();
System.out.println("result = " + result); // result = 6
}
}
- 메서드 호출이 체인처럼 연결된다. (`.add(1).add(2).add(3).getValue()`)
- 반환된 객체를 변수에 저장하지 않고 즉시 다음 메서드를 호출 가능하다.
- 메서드 체이닝이 가능한 이유는 자기 자신의 참조값을 반환하기 때문이다.
- 불필요한 코드가 줄어들고 가독성이 향상된다.
StringBuilder와 메서드 체이닝
StringBuilder의 체이닝 지원
- `StringBuilder`는 문자열을 변경하는 대부분의 메서드에서 자기 자신(this)을 반환하도록 설계되어 있다.
- 따라서 `.append()`, `.insert()`, `.delete()`, `.reverse()` 등의 메서드를 체이닝 방식으로 연속 호출 가능하다.
StringBuilder의 append() 구현 방식
public StringBuilder append(String str) {
super.append(str);
return this; // 자기 자신의 참조값 반환
}
이렇게 설계되어 있기 때문에, 체이닝 방식으로 문자열을 조작할 수 있다.
StringBuilder를 사용한 체이닝 예제
StringBuilder sb = new StringBuilder();
String string = sb.append("A").append("B").append("C").append("D")
.insert(4, "Java")
.delete(4, 8)
.reverse()
.toString();
System.out.println("string = " + string); // string = DCBA
- 일반적인 방식에서는 각 메서드를 호출할 때마다 `sb.`을 반복해야 하므로 코드가 길어진다.
- 위처럼 체이닝을 활용하여 한줄에 여러 메서드를 호출할 수 있다.
메서드 체이닝이 가능한 이유
메서드 체이닝 실행 과정
adder.add(1).add(2).add(3).getValue() // value=0
x001.add(1).add(2).add(3).getValue() // value=0, x001.add(1)을 호출하면 그 결과로 x001을 반환한다.
x001.add(2).add(3).getValue() // value=1, x001.add(2)을 호출하면 그 결과로 x001을 반환한다.
x001.add(3).getValue() // value=3, x001.add(3)을 호출하면 그 결과로 x001을 반환한다.
x001.getValue() // value=6
6
- 각 메서드가 자기 자신(`this`)을 반환하므로, 반환된 객체에서 계속 메서드를 호출할 수 있다.
- 체이닝 방식으로 `.` 을 사용하여 한 줄에서 여러 메서드를 호출 가능하다.
'Course > Java' 카테고리의 다른 글
[java-mid1] 5. 열거형 - ENUM (0) | 2025.03.15 |
---|---|
[java-mid1] 4. 래퍼, Class 클래스 (0) | 2025.03.12 |
[java-mid1] 2. 불변 객체 (0) | 2025.03.04 |
[java-mid1] 1. Object 클래스 (0) | 2025.02.25 |
[java-basic] 12. 다형성과 설계 (1) | 2025.02.24 |
댓글