본문 바로가기

Java/기본

[Java] 유용한 클래스 - String

개요

String 클래스는 java.lang 이라는 패키지에 속하는 클래스이다. 자바 프로그래밍에서 가장 기본이 되는 클래스이다. 엄밀히 따지자면 참조 자료형이지만 가장 기본적인 클래스이다 보니 기본 자료형(int, boolean, char)처럼 사용할 수 있는 혜택이 있는 클래스이다.

 

생성방법

String 클래스를 생성하는 방법에는 암시적 방법과 명시적 방법이 있다.

생성방법 example
명시적 생성 String str1 = new String("hello world");
암시적 생성 String str2 = "hello world";

 

먼저 리터럴 상수값을 저장할 수 있는 Constant Pool 이라는 영역이 있다. String, 숫자, 각종 문자열, 클래스, 메서드, 식별자, Class 및 Method 에 대한 참조값이 이 안에 들어가게 된다. 해당 객체와 관련된 모든 자원과 정보들을 모아 둔것인데, 클래스 어던 위치에서 호출을 하든지 접근해서 사용할 수 있도록 하는 영역이라고 보면 된다.

 

이때 암시적 객체생성시 Constant Pool에 같은 문자열 (위에서 예로든 "hello world")이 있다면 새로 등록하려는 절차를 중단하고 이미 등록된 참조변수 값을 가져온다.

반대로 명시적 객체생성시에는 Constant Pool을 확인하는 절차가 없이 바로 메모리(heap영역)에 새로 할당하게 된다.

 

String 클래스 생성자

생성자 내용
String() 비어있는 문자역 객체를 생성하고 초기화함
String(char[] ...) char[] 형 배열을 받아 문자열 생성
String(String str) str을 문자열로 하는 새로운 문자열 생성

 

주요 메서드

메서드 리턴타입 내용
charAt(int index) char index에 해당하는 char
equals(String otherString) boolean 문자열 비교
equalsIgnoreCase(String otherString) boolean 문자열 비교(대소문자 구분없이)
indexOf(int ch) int ch가 몇번째인지(없으면 -1 리턴)
length() int String의 길이 반환
concat(String next) String 문자열 연결
replace(String old, String new) String 문자열 중에서 new 로 바꾸고 싶은 부분을 바꾸기
replaceAll([정규표현식], String new) String 정규표현식에 해당하면 new 로 바꾸기
substring(int start) String start 부터 끝까지 끊어서 반환
substring(int start, int end) String start 부터 end 까지 끊어서 반환
split(String regex) String[ ] regex 기준으로 문자열 분리하기
toLowerCase() String 문자열 중에서 영어문자를 소문자로 모두 변환
toUpperCase() String 문자열 중에서 영어문자를 대문자로 모두 변환
endsWith(String end) boolean 주어진 문자열이 end로 끝나는가
lastIndexOf(int ch) int ch의 index 반환(오른쪽에서 계산). indexOf() 와 반대

 

 

String 객체의 특징

String 클래스로 문자열 객체를 한번 생성하고 나면 수정될 수 없다. 수정된 문자열을 수정할 때마다 새로운 객체가 생성된다. 예를들어 문자열을 10번 수정하면 문자열이 총 11개 생성된다는 의미이다. 마지막 객체를 제외한 나머지 10개는 GC(garbage collector)가 필요없어진 메모리 공간을 해제하게된다.

 

예를들어 위 메서드를 이용하여 String을 수정하였다고 하자. 그때도 실제로는 원래 값을 수정한 것이 아닌, 수정된 값으로 새로운 String 객체를 새로 생성하여 할당한 것이 맞다.

 

 

 

equals() 와 연산자 ==

equals() 문자열이 동등한지 비교
주소가 가리키는 문자열이 실제로 같은 값인지 비교
연산자 == 동일한 주소를 참조하는지(가리키는지) 비교

 

예제

같은 문자열 "hello world"를 부여했지만 어떤 비교를 하는지에 따라 참 거짓이 다르다는 것을 알 수 있다.

public class StringEx {
    public static void main(String[] args) {
        String str01 = new String("hello world");
        String str02 = new String("hello world");
        String str03 = "hello world";
        String str04 = "hello world";
        String str05 = new String("HELLO WORLD");
        String str06 = str05.toLowerCase();

        System.out.println(str01.equals(str02));    //true
        System.out.println(str02.equals(str03));    //true
        System.out.println(str03.equals(str04));    //true
        System.out.println(str04.equals(str06));    //true
        System.out.println(str01 == str02);         //false
        System.out.println(str02 == str03);         //false
        System.out.println(str01 == str03);         //false
        System.out.println(str03 == str04);         //true
    }
}

str04 라는 새로운 참조변수를 선언할 때는 Constant Pool에서 str03 선언시 등록했던 "hello world"라는 문자열을 확인하게 된다. "hello world"는 이미 등록된 문자열이므로 생성을 취소하고 생성된 str03 의 참조변수값을 받게된다. (같은 주소값을 가리키게 된다)