본문 바로가기

JAVA

Java String

728x90

우리는  문자열을 나타내는데 자바 스트링 객체를 많이 쓰지만, 사실 잘 알고 쓰는 사람은 별로 없는거 같다.

 

 

1) 스트링 리터럴? 스트링 객체?

 

JAVA 에는 문자열을 선언하는 두가지 방법이 있고 우린 혼용하지만 내부적인 구현은 완전히 다르다.

 

String s1 = new String("Boo");

String s2 = "Boo";

 

첫번쨰는 new 연산자를 이용하여 Heap 영역에 할당하는 것이고,

두번째는 String Constant Pool 이라는 특별한 상수 영역에 할당하는 것이다.

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

즉 s1 과 같은 방식으로 만들면 heap 계쏙해서 각각의 인스턴스를 생성하기 떄문에 다른 주소의 객체이나

s2와 같은 리터럴 방식으로 초기화 하면 String Constant Pool을 먼저 그 문자열이 있는지 체크하고,

없을때만 그 영역에 문자열을 만들고 있다면 그저 연결만 시켜준다.

 

이 프로그램을 보면 더 잘 이해가 될 것이다.

(== 는 객체 주소값의 비교이고 equals는 객체 안의 내용의 값을 비교하는 연산이다.)

1) s1 ,s2를 비교했을때 heap의 다른 인스턴스를 가르키므로 == 는 False equals는 true다.

2) s3,s4를 비교했을 때, String Constant Pool의 같은 리트럴을 가르키므로 == , equals 모두 true다.

3) s2 , s3를 비교했을 때 하나는 heap의 인스턴스를 가르키고 하나는 리트럴을 가르키므로 == 는 false 내용은 같기 때문에 equals는 true다.

 

ETC) 참고로 String 객체에는 intern이라는 함수가 있다.

이 함수는 객체와 동일한 문자열을 가진 but Constant String Pool에 있는 String 인스턴스를 리턴한다.

설명에는 다음과 적혀 있다.

 

/**
     * Returns a canonical representation for the string object.
     * <p>
     * A pool of strings, initially empty, is maintained privately by the
     * class {@code String}.
     * <p>
     * When the intern method is invoked, if the pool already contains a
     * string equal to this {@code String} object as determined by
     * the {@link #equals(Object)} method, then the string from the pool is
     * returned. Otherwise, this {@code String} object is added to the
     * pool and a reference to this {@code String} object is returned.
     * <p>
     * It follows that for any two strings {@code s} and {@code t},
     * {@code s.intern() == t.intern()} is {@code true}
     * if and only if {@code s.equals(t)} is {@code true}.
     * <p>
     * All literal strings and string-valued constant expressions are
     * interned. String literals are defined in section 3.10.5 of the
     * <cite>The Java&trade; Language Specification</cite>.
     *
     * @return  a string that has the same contents as this string, but is
     *          guaranteed to be from a pool of unique strings.
     */
    public native String intern();

 

또한 문자열의 가장 중요한 특징은 Immutable 즉, 값을 변경시킬수 없다는 것이다.

+나 concat와 같은 연산으로 문자열에 다른 문자열을 추가하면 기존 문자열의 내용이 바뀌는 것이 아니라

새로운 객체를 만들고 거기다가 바뀐 내용을 추가하고 새로운 객체를 리턴하는 것이다.

(그렇기 때문에 concat 등의 문자열 변경 함수가 String 값을 리턴해주는것 이다.)

 

'JAVA' 카테고리의 다른 글

JAVA 8 - 람다 추가  (0) 2020.08.15
JAVA 8 (2) - Optional  (0) 2020.08.15
웹서버 vs WAS  (0) 2020.08.07
StringBuilder vs StringBuffer  (0) 2020.07.02
JAVA 클래스의 == , equals 에 대해 알아보자  (0) 2020.06.03