본문 바로가기
컴퓨터/JAVA

[JAVA] 자바의 문자열과 문자열 메서드 정리

by 도도새 도 2023. 6. 13.

자바 문자열

 

String클래스는 자바에서 문자열을 나타내는 클래스이다. 이 String클래스는 불변(immutable)한 특징을 가진다. 이는 한 번 문자열 객체를 생성하면 변경할 수 없다는 의미이다.

다른 말로 하면, 이 문자열 객체에 새로운 문자열을 넣으면, 기존의 문자열을 수정하지 않고 새로운 문자열 객체를 생성하여 반환환다.

자바는 String 클래스에서 문자열을 다루는 다양한 메소드를 제공한다. 이에 대해서는 아래에 정리한다.

 

String 객체

 

String 객체는 기존의 객체와 마찬가지로 new키워드로 생성한다.

String s1 = new String("hello world");
String s2 = new String("hello world");
  • 이렇게 생성된 String 객체는 수정할 수 없다.
  • .concat(”문자열”)로 새로운 값을 넣은 변수를 생성할 수 있으나, 이는 새로운 객체를 생성하고 할당하는 것이다.
  • s1과 s2는 서로 다른 객체이다. 즉, 저장된 메모리의 주소가 다르다.
  • 이 객체는 JVM의 일반적인 힙에 저장된다.

 

문자열 리터럴을 이용하여 문자열 객체를 생성 할 수도 있다.

String s1 = "hello world";
String s2 = "hello world";
  • 이렇게 생성된 String 객체는 문자열 리터럴 풀(String Literal Pool)이라는 영역에 저장된다.
  • 문자열 리터럴을 이용시 동일한 문자열을 가지면(위의 경우) 동일한 주소를 가진다. 즉 이미 생성된 객체의 주소를 참조한다. 따라서 s1과 s2는 동일한 영역에 저장되어있다.
  • String Literal Pool은 JVM의 힙 안의 별도의 영역이다.

 

이에 대한 코드

public class Main {
    public static void main(String[] args) {
        String s1 = "String Litteral";
        String s2 = "String Litteral";

        if(s1 == s2) System.out.println("리터럴 : 같은 객체입니다!");
        else System.out.println("리터럴 :다른 객체입니다.");

        String s3 = new String("new operator");
        String s4 = new String("new operator");
        if(s3 == s4) System.out.println("리터럴 : 같은 객체입니다!");
        else System.out.println("리터럴 :다른 객체입니다.");

        if(s3.equals(s4)) System.out.println("equals : 같은 값을 가집니다!");
    }
}

 

 

출력값

리터럴 : 같은 객체입니다!
new :다른 객체입니다.
equals : 같은 값을 가집니다!

  • 객체의 ==연산의 경우 주소값이 같을 경우 true 아니면 false를 반환한다.
  • 리터럴로 생성시 객체는 String Literal Pool에 저장된다.
  • 같은 값 문자열 값을 가지는 s1과 s2는 같은 주소를 참조한다. 다시말해, s2는 s1의 주소를 참조하기에 같은 객체이다.
  • new연산자로 생성한 객체는 힙에 저장되며 객체마다 다른 주소를 가진다.
  • 따라서 ==연산시 서로 다른 주소를 가지므로 false를 반환한다.

 

주의: String의 비교는 .eqauls메소드를 쓰자.

 

아래의 경우를 보자.

public class Main {
    public static void main(String[] args) {
        String str = "h";
        str += "i";
        if(str == "hi"){
            System.out.print("correct!");
        }
        else{
            System.out.print("wrong!");
        }

        if(str.equals("hi")){
            System.out.print("correct2!");
        }
        else{
            System.out.print("wrong2!");
        }
    }
}

 

 

출력값

wrong!correct2!

 

  • 리터럴 리터럴로 str을 생성하고 추후 +연산을 하였다. 이때(+연산으로 새로운 값을 넣을 때,) 불변성 때문에 새로운 객체가 생성되고 힙에 할당된다.
  • 그러므로 str==hi 는 false가 된다. 서로 다른 주소를 참조하기 때문이다.

 

그러나 아래의 경우를 보자

public class Main {
    public static void main(String[] args) {
        String str = "hi";
        if(str == "hi"){
            System.out.print("correct!");
        }
        else{
            System.out.print("wrong!");
        }
    }
}

 

 

출력값

correct!

  • 이 경우는 true를 반환했음을 볼 수 있다.
  • 상수 풀에 저장된 문자열은 재사용된다. 즉 String constant pool에 한번 저장되면 동일한 문자열 상수를 다른 메모리 공간에 저장하지 않고 이미 저장된 문자열을 재사용한다.
  • 이 의미는 같은 문자열을 가지는 문자열 리터럴은 같은 주소를 가진다는 것이다! 따라서 “hi”와 str의 주소가 같기에 ==은 true가 된다.

 

문자열 메소드

 

메소드 설명
length() 문자열의 길이를 반환합니다.
charAt(int index) 지정된 인덱스에 해당하는 문자를 반환합니다.
concat(String str) 다른 문자열과 현재 문자열을 연결하여 새로운 문자열을 생성합니다.
substring(int beginIndex) 지정된 인덱스부터 끝까지의 문자열을 반환합니다.
substring(int beginIndex, int endIndex) 시작 인덱스부터 끝 인덱스 바로 전까지의 문자열을 반환합니다.
startsWith(String prefix) 주어진 접두사(prefix)로 시작하는지 여부를 반환합니다.
endsWith(String suffix) 주어진 접미사(suffix)로 끝나는지 여부를 반환합니다.
toLowerCase() 문자열을 소문자로 변환한 새로운 문자열을 반환합니다.
toUpperCase() 문자열을 대문자로 변환한 새로운 문자열을 반환합니다.
trim() 문자열의 앞뒤 공백을 제거한 새로운 문자열을 반환합니다.
replace(char oldChar, char newChar) 문자열에서 지정된 문자(oldChar)를 새로운 문자(newChar)로 대체한 새로운 문자열을 반환합니다.
split(String regex) 지정된 정규 표현식(regex)을 기준으로 문자열을 분할하여 문자열 배열로 반환합니다.
equals(Object obj) 다른 객체와 문자열을 비교하여 동등한지 여부를 반환합니다.
equalsIgnoreCase(String anotherString) 대소문자를 무시하고 다른 문자열과 동등한지 여부를 반환합니다.
contains(CharSequence sequence) 지정된 문자열 또는 문자열 시퀀스(sequence)가 포함되어 있는지 여부를 반환합니다.
isEmpty() 문자열이 비어있는지 여부를 반환합니다.
indexOf(String str) 주어진 문자열(str)이 처음으로 나타나는 인덱스를 반환합니다.
lastIndexOf(String str) 주어진 문자열(str)이 마지막으로 나타나는 인덱스를 반환합니다.

댓글