Java

[Java]String 리터럴(Literal), String 객체(Object)

DevStory 2021. 5. 12.

Java에서 문자열을 생성하는 과정은 2가지 방법이 있습니다.

1. 문자열 리터럴(Literal)을 사용

public class Main {
  public static void main(String[] args) {
    String strLiteral1 = "TEST";
    String strLiteral3 = "TEST";
    String strLiteral2 = "Java";
  }
}

 

2. new String()을 사용

public class Main {
  public static void main(String[] args) {
    String strObject1 = new String("TEST");
    String strObject2 = new String("TEST");
    String strObject3 = new String("Java");
  }
}

리터럴(Literal)과 new String()의 차이점

문자열 리터럴(Literal)의 생성 과정

public class Main {
  public static void main(String[] args) {
    String strLiteral1 = "TEST"; // 1번 과정
    String strLiteral2 = "TEST"; // 2번 과정
    String strLiteral3 = "Java"; // 3번 과정
  }
}

 

생성 과정

1. String Pool에 "TEST"가 생성됩니다.
2. JVM이 String Pool에 "TEST"가 이미 존재하므로 strLiteral2은 1번 과정에서 생성된 "TEST"를 참조합니다.
3. String Pool에 "Java"가 생성됩니다.

new String()의 생성 과정

public class Main {
  public static void main(String[] args) {
    String strObject1 = new String("TEST"); // 1번 과정
    String strObject2 = new String("Java"); // 2번 과정
    String strObject3 = new String("TEST"); // 3번 과정
  }
}

생성 과정

1. Java Heap에 "TEST"가 생성됩니다.
2. Java Heap에 "TEST"가 생성됩니다.
3. Java Heap에 "Java"가 생성됩니다.


문자열 리터럴(Literal)과 다르게 new String()으로 생성된 문자열은 Java Heap 영역에 생성이 됩니다.
그리고 동일한 문자열이라도 기존의 문자열을 참조하지 않고 새로 생성 됩니다.


String Pool은 무엇인가?

String Pool은 Java Heap의 저장 영역입니다.

JVM은 과도한 String 개체의 수를 줄이고자 문자열 리터럴이 생성될 때마다 String Pool을 체크합니다.
문자열이 이미 String Pool에 존재하는 경우에는 인스턴스에 대한 참조가 반환됩니다.
존재하지 않으면 새로운 인스턴스가 String Pool에 생성이 됩니다.

 

일반적으로 리터럴(Literal)을 사용하는 것이 읽기가 더 쉬우며, 컴파일러가 코드를 효율적으로 최적화합니다.


== vs equals()

public class Main {
  public static void main(String[] args) {
    String strLiteral1 = "TEST";
    String strLiteral2 = "TEST";
    String strLiteral3 = "Java";
    
    String strObject1 = new String("TEST");
    String strObject2 = new String("TEST");
    String strObject3 = new String("Java");
    
    System.out.println("strLiteral1 == strLiteral2 : " + (strLiteral1 == strLiteral2));
    System.out.println("strObject1 == strObject2   : " + (strObject1 == strObject2));
    System.out.println("strLiteral1 == strObject1  : " + (strLiteral1 == strObject1) + "\n");
    
    System.out.println("strLiteral1.equals(strLiteral2) : " + (strLiteral1.equals(strLiteral2)));
    System.out.println("strObject1.equals(strObject2)   : " + (strObject1.equals(strObject2)));
    System.out.println("strLiteral1.equals(strObject1)  : " + (strLiteral1.equals(strObject1)));
  }
}

== Operator

동일한 메모리 공간인지 비교를 하는 연산자입니다.

 

Equals()

객체의 내용을 비교하는 메소드입니다.

 

위 코드의 문자열 리터럴(Literal)과 new String() 객체의 Heap Memory 구조는 아래 그림과 같습니다.

== Operator 연산자를 사용한 코드에 대해서만 설명합니다.

 

▶ strLiteral1 == strLiteral2

strLiteral1과 strLiter2는 동일한 공간을 참조하고 있습니다.

즉, 참조하는 주소가 같으므로 true입니다.

 

▶ strObject1 == strObject2

strObject1과 strObject2는 다른 공간을 참조하고 있습니다.

즉, 참조하는 주소가 다르므로 false입니다.

 

strLiteral1 == strObject1

strLiteral1과 strObject2는 다른 공간을 참조하고 있습니다.

strLiteral1은 String Pool 내부의 공간을 참조합니다.

strObject2는 String Pool 외부의 공간을 참조합니다.

즉, 참조하는 주소가 다르므로 false입니다.

 

반응형

'Java' 카테고리의 다른 글

[Java]객체(Object)를 XML로 변환  (0) 2022.04.11
[Java]main 함수(메서드)  (0) 2022.04.10
[Java]현재 날짜 및 시간 가져오기  (0) 2022.04.09
[Java]날짜 비교 방법  (0) 2022.04.05
[Java]생성자 체인(Constructor Chaining)  (0) 2021.10.13

댓글