Little cabin in the woods

String 자료형 선언 방식 비교 (리터럴 vs new 연산자) 본문

STUDY/JAVA

String 자료형 선언 방식 비교 (리터럴 vs new 연산자)

Y... 2024. 4. 4. 23:59

Java에서 문자열을 표현하는 String 자료형은 원시 타입 자료형이 아닌, 참조 타입 자료형에 속한다.

이에 따라 new 연산자를 사용하여 String 객체의 인스턴스를 생성하는 방식으로 선언하지만, 문자열은 매우 자주 사용되는 자료형이기 때문에 원시값처럼 리터럴로 선언할 수도 있게 되어있다.

//리터럴 방식
String str1 = "Hello World!";

//new 연산자 사용
String str2 = new String("Hello World!");

 

단, 리터럴로 생성하는 방식과 new 연산자로 생성하는 방식은 내부 동작 방식이 조금 다르다.

String hl1 = "Hello";
Stirng hl2 = "Hello";
String wld = "World";

boolean bool1 = hl1 == hl2; //bool1=True
boolean bool2 = hl2 == wld; //bool2 =False;

 

위의 코드와 같이 리터럴로 생성했을 시에는 == 연산자를 사용하여 문자열이 같은 지 비교하는 것이 가능하다.

 

하지만, new 연산자로 생성했을 시에는 문자열이 같은 지 비교하기 위해 == 연산자를 사용하면 안된다.

대신, ".equals" 메소드를 사용해야 한다. 

String hl3 = new String("Hello");
String hl4 = new String("Hello");

boolean bool3 = hl3==hl4; //bool3=False

boolean bool4 = hl3.equals(hl4); // b00l4=True

 

== 연산자는 변수의 값이 저장된 주소가 같은지 비교하는 연산자이기 때문이다.

값 자체를 비교하는 건 equals 메서드를 통해 한다.

 

리터럴로 생성했을 때와  new 연산자로 생성했을 때 값이 저장되는 과정을 그림으로 표현하면 아래와 같다.

 

출처 : https://www.yalco.kr/lectures/java/

 

문자열을 리터럴 방식으로 생성했을 때는 hl1, hl2, wld 와 같이 힙 영역의 String constant pool 이라는 곳에 값이 저장된다. 이때, 만약 담아야 하는 값이 같다면 새롭게 공간을 생성하지 않고, 같은 문자열이 적힌 주소를 가리키도록 저장하여 중복 없이 저장할 수 있다.

 

하지만 new 연산자를 통해 객체의 인스턴스를 생성할 시, hl3과 hl4가 그림에서 각각 다른 공간에 위치하는 것처럼 힙 영역에 매번 새로운 공간이 생성된다. 

String hl5 = hl4;

boolean bool5 = hl5==hl4; // bool5=True
boolean bool6 = hl5.equals(hl4); //bool6=True

 

다만 위의 코드처럼 이미 선언되어 있는 변수를 새로운 변수에 넣어줄 때에는, 두 변수가 같은 주소 공간을 가리키도록 하는 방식으로 동작한다. 위 그림에서 hl4와 hl5가 같은 공간을 가리키는 것은 그 때문이다.

 

헷갈리면 안되는 점은 리터럴로 선언했어도, 값이 저장되는 공간만 다를 뿐, String 객체로 만들어지는 것은 같다는 것이다.  따라서 아래와 같이 객체의 기능인 메서드를 사용하는 것이 가능하다. 문자열은 워낙 자주 사용되는 인스턴스 데이터이기 때문에 리터럴로 생성하는 방식도 추가적으로 제공하는 것이라고 생각하면 된다.

String s1 = "안녕";
boolean b1 = s1.equals("안녕"); // String 객체의 메서드인 equals 사용 가능 , b1 = True

 

* 참고로 equals는 대소문자를 비교하여 비교한다. 만약 대소문자를 구분하지 않고 비교하고 싶다면 equalsIgnoreCase 메서드를 사용해야 한다.

 

**이 글은 [인프런 - 제대로 파는 JAVA : 얄팍한 코딩사정(얄코) ] 강의를 수강 후, 참고하여 작성되었습니다.