ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java String
    Develop/Java 2020. 11. 13. 08:41

    String 문자열의 생성

     

    일반 객체를 생성할 경우 ⇒ new 키워드를 사용한다.

    String은 new가 없어도 바로 값 할당이 가능하다. 이를 문자열 리터럴이라고 한다.

     

    new 연산자는 생성된 값을 heap에 할당하고, 리터럴 연산자는 String Constant Pool에 할당한다.

    Java7부터는 Heap으로 할당한다. 이전에는 Perm 영역에 Constant Pool이 존재했다. Java 8부터 Perm영역이 삭제되었다. Heap은 GC의 대상이라, 참조를 잃을 경우 다시 메모리로 반환된다.

     

    String 1 = "aaa"; 
    String 2 = "aaa"; 
    //1과 2는 String constant pool 내의 같은 객체를 참조한다. 
    String 3 = new String("aaa"); 
    String 4 = new String("aaa"); 
    //3과 4는 Heap 영역에서 각자 다른 객체를 참조하고 있다.

    String Equals() / ==

    .equals()

    동일한 주솟값을 가지는 객체이거나, 문자열 내부의 이 동일할 경우 true를 리턴한다.

    ==

    실제 객체가 가지고 있는 주솟값을 비교하는 연산자이다.

    Primitive Type의 경우 객체가 아니기 때문에 값 비교나 마찬가지이다.

     

    리터럴 내부 함수

    • String Intern() method

      String Constraint Pool에 생성하려는 문자열이 이미 존재할 경우 주소값을 return하고, 존재하지 않을 경우에는 새 객체를 생성한 후에 주소값을 return한다.

     

    문자열은 Immutable하다

    문자열 리터럴은 상수로서 불변하다. 그래서 참조하려는 문자열이 같으면, 동일 객체를 참조하는것이다.

    JVM에서 String Constraint Pool을 check하고 존재할 경우 재사용하고, 존재하지 않을경우에는 생성한다.

    immutable, 즉 thread safe함을 말하는데, String 연산은 immutable해서 연산을 진행할 경우 새로 String 객체를 생성하고 연산 결과를 집어넣는다.

     

    Java String은 성능 최적화를 위해 문자열 연산의 경우 내부족으로 String Builder를 사용한다. ⇒ 리터럴을 생활화하자

     

    StringBuilder / StringBuffer

    내부적으로 동적 배열로 구현되어있다. 연산 작업시 StringBuilder를 생성하여 사용하고, 마지막에 .toString()해도 된다.

     

    차이점

    Synchronized 여부이다. StringBuffer는 synchronized를 지원하기 때문에 멀티스레드 환경에서 매우 안전하다. 하지만 lock을 걸고 푸는 동기화가 있어 속도는 느리다.

     

    Buffer는 멀티스레드 환경에서 안전을 보장해야 할 때 사용하고, singleton을 변경하거나 static을 변경할 때 사용하자. Builder는 스레드 여부와 상관 없고, 메서드 내에서 지역변수로 사용할 때 사용하자.

     

     

     

    ref.

    https://woowacourse.github.io/javable/2020-09-07/dive-into-java-string

    댓글

Designed by Tistory.