자바9의 String 변화

이영진·2022년 8월 9일
0
post-custom-banner

자바9에서 왜 String에 변화가 일어났는지

Java9이전에는 내부적으로 유니코드중 하나인 UTF-16을 사용하기때문에 모든문자는 2바이트로 구성됩니다.
2바이트로 구성되었던 이유는 영문,숫자,특수문자를 표현하는 아스키코드는 1바이트로 표현이 가능했지만,
한글,한자 뿐아니라 세계적인 언어들을 사용하기위해서는 1바이트(8bit) 인 2^8 = 256 자로 전부 표현할수없게되어
자바에서는 유니코드를 사용합니다.

Java의 String은 내부적으로 문자를포함하는 char[]로 표현되었었고
String str = "abc";는 사실상 아래와 같습니다

char data[] ={'a', 'b', 'c'};
String str = new String(data);

그런데 String은 항상 2바이트가 필요한것은 아닙니다.
한문자만 필요한경우에는 1바이트만 제공해도 문제가없기때문에 자바9에서는 문자열을 최적화 하게되었습니다.

문자표현방식중 LATIN-1, UTF-16표현이 있는데 전자는 1바이트를 제공하게되고 후자는 2바이트를 제공하게됩니다.

자바9 이전에는 내부적으로 UTF-16만을 사용하여 모든문자가 2바이트로 구성되었지만
(JDK6에서 문자열 최적화하는 VM옵션이있었지만 의도치않은 성능결과로인해 JDK7에서 사라지긴했습니다)
자바9이후로는 LATIN-1표현을 사용하여 char[]가아닌 byte[]로 문자열을 저장하게 됩니다.

default 문자표현방식이 LATIN-1 설정되었다

String 클래스를 조금 살펴보겠습니다

private final byte coder;  // 인코딩방식 (LATIN-1, UTF-16)을 저장

String 클래스에는 coder라는 필드값이 존재하는데 위에서말한 인코딩방식(LATIN-1, UTF-16)을 식별하기위한 필드값입니다

기본적으로 문자열 최적화한다는 의미인 COMPACT_STRINGS값을 true로 주면서
문자열최적화가 디폴트값임을 알수있습니다

새 String을 할당할때에도 COMPACT_STRINGS이 맞다면 LATIN(1바이트)방식을 사용하여 인코딩방식과 값을 저장합니다
=> 기본값인 COMPACT_STRINGS 이 true이므로, 기본문자표현방식이 LATIN1임을 알수있습니다.


문자열의 길이를 구할때도 문자열의 유니코드단위수에 따라서 정해집니다


위의 indexOf()에서는 coder값을 확인후 그에 걸맞는 방식으로 내부로직을 수행합니다.
indexOf() 뿐아니라 charAt(), startsWith(),indexOf()등등 수많은 메서드에서 위와비슷한 흐름으로 진행됩니다

어떤 문자가 들어오느냐에 따라 문자표현식이 변경된다

String a = new String("abcde"); // LATIN-1 문자표현식을 사용해도 충분하다. byte[]가 생성되어 저장된다

String b = new String("ab€€€"); // LATIN-1 문자표현식으로 €문자를 표현할수없다. 자바는 이때 UTF-16을 사용한다 char[]가 생성되어 저장된다 

정리

자바9 이전에는 String에서 1바이트만 필요한경우에도 UTF-16 문자표현방식으로 2바이트를 제공했지만, 자바 9이후로는 LATIN-1표현을 사용하여 char[]가 아닌 byte[]로 문자열을 저장한다. 메모리소비와 성능을 조금더 최적화 했다고 볼수있다.

post-custom-banner

0개의 댓글