문자열의 표현과 객체 생성
참조 자료형의 가장 대표적인 형태는 클래스이다. 클래스 중 문자열을 저장하는 게 String 클래스다. 문자열은 반드시 큰따옴표(String a = "문자열")안에 표기해야 한다. String a = "" 와 같이 아무런 문자열이 오지 않아도 상관없다. 하지만, 큰따옴표는 생략 할 수 없다. String 클래스의 객체를 생성하는 데는 크게 2가지 방법이 있다. 첫 번째는 new 키워드를 사용하는 방법으로 생성자의 입력 매개변수로 지정할 문자열을 입력한다.
String 참조변수명 = new String("문자열");
대부분의 클래스가 이 방법으로 객체를 생성한다. 생성자는 아직 배우지 않았지만 클래스명과 동일하면서 뒤에 소괄호가 있는 형태다. 두 번째 방법은 간단히 문자열 리터럴, 즉 문자열 값만 입력하는 방법이다.
String 참조변수명 = "문자열";
두 방법 모두 메모리에 저장되는 방식은 동일하다.
String 클래스의 2가지 특징
String 클래스는 다른 클래스에 없는 2가지 특징이 있다. 1. 한 번 정의된 문자열은 변경할 수 없다. 만약 문자열의 내용을 변경하면 자바 가상 머신은 기존의 문자열을 새로운 문자열을 포함하고 있는 객체를 생성해 사용하고 기존의 객체는 버린다. 즉, 참조 변수가 가리키고 있는 힙 메모리의 주소가 바뀌는 것이다.
String str1 = new String("안녕");
String str2 = str1;
str1 = "안녕하세요";
위 코드를 보면 "안녕"이라는 문자열을 생성하고 그 주소를 str1에 저장한다. 다음 행에서 str2에 str1을 대입한다. str1, str2가 같은 주소를 가리키게 된다. 세 번째 행에서 str1의 문자열을 수정한다. 이 때, str1의 주소가 바뀌게 되면서, str1, str2는 서로 다른 주소를 가리키게 된다. 새로운 객체가 생성되었기 때문이다. 한편, 배열은 객체의 값 자체가 수정되므로 참조 변수 복사 이후 하나의 변수에서 수정하면 나머지 변수에도 적용된다. 새로운 객체를 만들지 않고 기존 객체의 내용을 수정하기 때문이다.
2. 문자열 리터럴을 바로 입력해 객체를 생성할 때 같은 문자열끼리 객체를 공유한다. 문자열 리터럴만 입력해 String 객체를 생성하면 하나의 문자열을 여러 객체가 공유할 수 있다. 특정 문자열의 객체를 여러 개 만들어 사용할 때 메모리 효율성을 증가시키기 위한 것이다. new 키워드로 객체를 생성하게 되면 동일한 문자열 객체가 힘 메모리에 있든, 없든 무조건 새롭게 객체를 생성한다. 문자열 리터럴로 생성할 때는 힙 메모리에 리터럴로 생성된 동일 문자열을 포함하고 있는 객체가 있으면 그 객체를 공유한다. 위 코드에서 두 번째 행이 하는 역할과 같다.
String 객체의 '+' 연산
String 객체는 + 연산을 이용해 문자열을 연결(더하기가 아니라 연결하기)할 수 있다. String 객체의 + 연산은 두 가지 형태가 있다.
1. '문자열 + 문자열' 연산
String str1 = "안녕" + "하세요" + "!";
출력한다면 결과는 "안녕하세요!"라는 것을 쉽게 예측할 수 있다. 하지만, 메모리에선 이 한 줄의 명령어로 객체가 5개나 만들어진다. String 객체의 내용을 변경할 수 없으므로 연산 수행 과정을 거치면서 "안녕", "하세요", "!", "안녕하세요", "안녕하세요!" 총 5개의 객체가 만들어진다. 참조 변수에는 마지막 객체의 주소가 저장된다.
2. '문자열 + 기본자료형' 또는 '기본자료형 + 문자열' 연산
모든 연산은 동일한 자료형끼리만 가능하다. 따라서 기본 자료형과 문자열을 연산한려면 먼저 기본 자료형을 문자열로 바꿔주고 '문자열 + 문자열' 연산을 수행한다. 주의할 점은 연산의 순서이다. 1+"안녕"+2 와 1+2+"안녕" 의 연산 결과는 각각 "1안녕2"와 "3안녕"으로 다르다. + 연산은 앞에서부터 순차적으로 수행되므로 순서에 주의해야 한다.
String 클래스의 주요 메서드
구분 | 리턴 타입 | 메서드 | 설명 |
문자열 길이 | int | length() | 문자열의 길이 |
문자열 검색 | char | charAt(int index) | 인덱스 위치에서의 문자 |
int | indexOf(int ch) indexOf(int ch, int fromIndex) indexOf(String str) indexOf(String str, int fromIndex) |
문자열에 포함된 문자 또는 문자열의 위치를 앞에서부터 검색했을 때 일치하는 인덱스 값 (fromIndex는 검색 시작 위치) |
|
int | lastIndexOf(int ch) lastIndexOf(int ch, int fromIndex) lastIndexOf(String str) lastIndexOf(String str, int fromIndex) |
문자열에 포함된 문자 또는 문자열의 위치를 뒤에서부터 검색했을 때 일치하는 인덱스 값 (fromIndex는 검색 시작 위치) |
|
문자열 변환 및 검색 | float | String.valueOf(boolean b) String.valueOf(char c) String.valueOf(int i) String.valueOf(long l) String.valueOf(float f) String.valueOf(double d) |
boolean, char, int, long, float, double 값을 문자열로 변환하기 위한 정적 메서드 |
double | concat(String str) | 문자열 연결(String 객체의 + 연산과 동일) | |
문자열 배열 변환 | byte[] | getBytes() getBytes(Charset charset) |
문자열을 byte[]로 변환(변환할 때 문자셋(charset) 지정 가능) |
char[] | toCharArray() | 문자열을 char[]로 변환 | |
문자열 수정 | String | toLowerCase() | 영문 문자를 모두 소문자로 변환 |
String | toUpperCase() | 영문 문자를 모두 대문자로 변환 | |
String | replace(char oldChar, char newChar) | oldChar 문자열을 newChar 문자열로 대체한 문자열 생성 | |
String | substring(int beginIndex) substring(int beginIndex, int endIndex) |
beginIndex부터 끝까지의 문자열 생성 beginIndex부터 endIndex-1 위치까지의 문자열 생성 |
|
String[] | split(String regex) split(String regex, int limit) |
regex를 기준으로 문자열을 분할한 문자열 배열을 생성(regex 구분기호는 '|' 기호로 여러 개 사용 가능, limit는 분할의 최대 개수) | |
String | trim() | 문자열의 앞뒤 공백 제거 | |
문자열 내용 비교 | boolean | equals() | 문자열의 실제 내용 비교(==는 매모리 번지(stack) 비교) |
boolean | equalsIgnoreCase(String anotherString) | 대소문자 구분없이 문자열의 실제 내용 비교 |
'development > Java' 카테고리의 다른 글
JAVA 공부 해볼까 (11) (0) | 2021.12.20 |
---|---|
JAVA 공부 해볼까 (10) (6) | 2021.12.18 |
JAVA 공부 해볼까 (8) (4) | 2021.12.14 |
JAVA 공부 해볼까 (7) (2) | 2021.12.13 |
JAVA 공부 해볼까 (6) (0) | 2021.12.11 |