언어(Language)/Java

[Java] 자바의 문자열 클래스 정리 (String class, 인스턴스)

잇트루 2022. 9. 6. 22:00
반응형

스트링 클래스란? (String class)

자바에서는 문자열을 데이터 타입이 아닌 클래스로 다룬다. 이는 자바에서 클래스를 데이터 타입 그 자체로 사용될 수 있기 때문이다. 따라서 클래스와 그 연관된 기능(메서드)들을 묶을 수도 있다.

즉, 자바에서는 String 클래스를 문자열 데이터 타입으로 사용하며, 문자열과 관련된 유용한 메서드들을 가지고 있다.

 

문자열 변수 선언과 할당

기본적으로 String 타입은 변수 선언 시 큰 따옴표(””)를 사용한다. 자바에서 큰 따옴표(””)로 감싸진 데이터들은 문자열로 인식하게 된다. 문자열을 선언할 시, 기존의 방식과 유사한 문자열 리터럴을 문자열 변수에 할당하는 방법과 String 클래스의 인스턴스를 생성하는 방법이 있다.

class StringEx {
    public static void main(String[] args) {
        // 기존의 변수 선언 방식
        String str1 = "Hello world!";
		
        // String 클래스의 인스턴스를 생성하는 방법
        String str2 = new String("Hello Java!");
    }
}

String 타입은 클래스 자체를 데이터 타입으로 사용하여 기본 변수 선언 방식처럼 사용할 수 있다.

또한, 다른 방식인 String 클래스의 인스턴스를 생성할 때, 자신을 생성한 클래스를 데이터 타입으로 가진다.

 

두 방식의 공통점

위 두 방식을 이용할 때 참조 타입의 변수에 할당되는 공통점이 있다. 즉, 위 예제에서 str1과 str2는 실제 문자열의 내용을 값으로 가지고 있는 것이 아니라, 문자열이 존재하는 메모리 공간 상의 주소 값을 저장하고 있다.

class StringEx {
    public static void main(String[] args) {
        String str1 = "Hello world!";
        String str2 = new String("Hello Java!");

        System.out.println(str1); // 출력 : Hello world!
        System.out.println(str2); // 출력 : Hello Java!
    }
}

하지만, 출력할 때는 주소 값을 출력하는 것이 아닌 문자열의 내용을 출력하게 된다.

이러한 이유는 String 타입의 변수를 참조하면 String 클래스의 메서드인 toString()이 자동으로 호출되기 때문이다. 즉, toString() 메서드가 호출되면, String 타입의 변수가 저장하고 있는 주소 값에 위치한 String 인스턴스의 내용을 문자열로 변환한다.

 

두 방식의 차이점

이 두 방식의 차이점은 위해 비교 연산자(==)와 equals() 메서드를 사용하면 확인할 수 있다.

 

비교 연산자(==)

비교 연산자는 ‘좌항 == 우항’ 형태로 사용하여 좌항의 값과 우항의 값이 일치하는 지를 검사한다. 좌항의 값과 우항의 값이 일치하면 true를, 그렇지 않으면 false를 반환한다.

 

equals() 메서드

equals() 메서드는 '.'앞의 변수가 저장하고 있는 내용과 () 안의 내용이 같은지를 비교하여 같으면 true를, 그렇지 않으면 false를 반환한다.

class StringEx {
    public static void main(String[] args) {
        String str1 = "Hello World!";
        String str2 = "Hello World!";

        String str3 = new String("Hello World!");
        String str4 = new String("Hello World!");

        System.out.println(str1 == "Hello World!");      // true
        System.out.println(str1 == str2);                // true
        System.out.println(str1 == str3);                // false
        System.out.println(str1 == str4);                // false
        System.out.println(str3 == str4);                // false

        System.out.println(str1.equals("Hello world!");  // true
        System.out.println(str1.equals(str2);            // true
        System.out.println(str1.equals(str3);            // true
        System.out.println(str1.equals(str4);            // true
        System.out.println(str3.equals(str4);            // true
    }
}

위 결과를 살펴보면, equals() 메서드를 사용했을 때, “Hello World!”라는 내용이 모두 똑같다고 판단하여 true를 반환한다. 하지만, 비교 연산자(==)를 사용했을 때는 예상했던 결과와는 다르게 나타난다.

이러한 결과는 할당 방식에 의한 결과이다. str1과 str2는 String 타입의 변수에 직접 할당하는 방식을 사용하고 있다. 이는 참조하고 있는 주소 값이 일치하다는 뜻이다. 따라서 참조하고 있는 메모리가 같기 때문에 데이터 또한 같은 값을 공유하고 있다.

반면에 str3와 str4는 클래스의 인스턴스를 생성하는 방식이다. String 클래스의 인스턴스를 생성하게 되면 문자열의 내용이 같을 지라도 별개의 인스턴스가 생성되어 서로 다른 주소 값을 가지게 된다.

즉, str3와 str4는 주소 값이 다르기 때문에 str1, str2와 다를뿐더러 str3, str4는 서로 다른 주소 값을 가지게 되는 것이다.

 

간단 정리

비교 연산자(==)는 저장된 값을 비교하는 것으로 주소 값이 저장된 변수는 주소 값을 비교한다.

equals() 메서드는 주소 값과는 별개로 저장하고 있는 내용을 비교한다.

일반 변수 선언 방식으로 String 클래스의 변수를 생성하면 공통된 주소 값을 갖게 되어 서로 공유한다. (내용도 같고 주소 값도 같다.)

String 클래스의 인스턴스를 생성하면 문자열 내용이 같을지라도, 별개의 인스턴스가 생성되는 것으로 서로 다른 주소 값을 갖게 된다.

 

 

반응형