Java) String 객체 비교 시 주의할 점 + String만 객체로 취급되는 이유?

2022. 1. 17. 22:38코딩/JAVA

안녕하세요. brandy 입니다. 

코드프레소 자바 강의를 수강하던 중에 궁금한 점이 생겨서 따로 포스팅을 하게 되었습니다. 

 

자바에서 String 문자열을 자주 사용하는데, String에 대해서 좀 더 알아보고자 글을 작성하게 되었습니다. 

 

물론 Java를 사용하다 보면 '객체' 그리고 '클래스'라는 개념은 빼놓을 수가 없는 단어인데요..! 

이 참에 String이 왜 객체로 취급되는지에 대해 좀 더 알아보고자 합니다(다른 int형이나 float 등은 객체로 취급이 안되는데 왜 String만 객체로 취급이 되는지?) 

 

- String 객체 대부분은 원시(Primitive 기본) 타입으로 취급되어 new 키워드를 사용하지 않아도 된다 > Stack에 저장 

But, Java에서 String은 특별한 참조 자료형으로 다른 객체들과 마찬가지로 new 생성자를 이용해 인스턴스를 만들고 heap 영역에 올라가지만, 다른 참조형들과는 다르게 한 번 객체가 생성되면 해당 값은 불변. 

 

- new 연산자를 이용해 문자열을 생성하게 되면, 메모리의 heap 영역에 할당된다. 

또한 new 키워드를 이용해 객체를 생성하면 객체가 계속 생성되어 성능에 좋지 않다고 한다. 

String str1 = new String("Hello!");

- 리터럴(데이터 그 자체)방식으로 문자열을 생성한다면 String Constant Pool 이라는 영역에 할당된다. 

String str2 = "Hello!";

"Hello!"가 리터럴이다. 

" "로 생성하면 객체는 한 번만 생성된다. 

 

 

 

String str1 = "madplay";
String str2 = "madplay"; 
String str3 = new String("madplay"); 
String str4 = new String("madplay");

 

 

 

https://madplay.github.io/post/java-string-literal-vs-string-object

 

자바 heap 영역에 매핑해본다면, 상수풀(String constant pool)에 생성된 문자열의 경우 하나만 존재하게 된다. 

따라서 str1과 str2는 같은 문자열을 참조하게 된다.

반대로 heap 영역에 객체를 생성한 경우 각각의 인스턴스가 생성되기 때문에 str3, str4는 각각 다른 문자열을 참조한다. 

 

※ Heap 영역이란? 

메모리의 Heap 영역은 사용자가 직접 관리할 수 있는 , 그리고 해야만 하는 메모리 영역이다. 힙 영역은 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다. 힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다. 

 

 

 

리터럴과 new 키워드로 작성한 String 문자열의 비교 

public class Codepresso_java1 {
    public static void main(String[] args) {
        String name1 = "CodePresso";
        String name2 = new String("CodePresso");
        String name3 = "CodePresso";

        System.out.println(문자열 비교); 
    }
}

위의 개념들을 바탕으로, name1은 리터럴로 문자열을 생성하였으며 name2는 new 키워드를 이용하여 문자열을 생성하였다. 

 

1) 리터럴 vs 리터럴 

'같다'의 비교 연산자는 == 입니다. 반환값은 boolean(true,false) 형태로 나타납니다. 또한 == 는 객체의 주소값을 비교합니다. 

 

리터럴로 생성된 문자열인 name1과 name3을 비교해보겠습니다.

System.out.println(name1==name3);

출력 결과는 true입니다. 

 

2) 리터럴 vs new 키워드 

System.out.println(name1==name2);

false가 반환됩니다. 그리고 리터럴과 new 키워드로 작성된 문자열을 비교할 때는 ==이 아닌 

equals() 메소드를 이용해주어야 하는데요, == 연산의 경우 객체의 주소값을 비교하는데, new 연산자를 통해 힙 영역에 생성된 String과 String Constant Pool영역에 위치한 String의 주소값은 같을 수가 없습니다. 

 

 

 

 

 

참고 https://it-mesung.tistory.com/46

 

 

[Java 기초] String 객체를 알아보자

String 사용? 미사용? String은 메모리에 어떻게 저장되는가? 객체의 값은 변경가능 한가? String 객체 대부분은 원시(Primitive) 타입으로 취급하므로 new 키워드를 사용할 필요가 없다. new 키워드를 사용

it-mesung.tistory.com

 

https://madplay.github.io/post/java-string-literal-vs-string-object

 

자바의 String 객체와 String 리터럴

자바에서 문자열을 선언하는 방법은 두 가지가 있다. String과 new String()은 어떤 차이가 있을까?

madplay.github.io

 

잘못된 부분이 있다면 언제든지 지적 환영합니다!