2010-12-15 4 views
33

자바에서 문자열의 인코딩과 관련하여 실제로 혼란 스럽습니다. 나는 몇 가지 질문이있다. 그들에 대한 답을 알고 있다면 도와주세요 :Java에서 String의 문자 인코딩은 무엇입니까?

1) 메모리에있는 Java 문자열의 기본 인코딩은 무엇입니까? 내가 String a = "Hello"을 쓸 때 어떤 형식으로 저장 될까요? 자바는 기계에 독립적이기 때문에 시스템이 인코딩을 수행 할 것이라고는 생각하지 않습니다.

2) "UTF-16"이 기본 인코딩이라는 것을 읽었지 만, 그 문자를 쓸 때 말하기 때문에 혼란 스러웠습니다. int a = 'c' ASCII 테이블의 문자 수를 얻었습니다. 그래서 ASCII와 UTF-16은 같은가요?

3) 또한 메모리에 저장되는 문자열의 저장 위치에 대해 확신하지 못했습니다. OS, 언어?

+0

당신은 그들이 정말 다른만큼, 각각의 질문에 다음을 깨는 고려해야한다. # 2는 여기에서 아마도 대답 할 수 있습니다 : http://stackoverflow.com/questions/1490218/utf-16-to-ascii-conversion-in-java –

답변

15

1) 문자열은 일반적으로 char 배열과 문자열의 길이를 포함하는 객체입니다. 문자 배열은 일반적으로 16 비트 단어의 연속 배열로 구현되며, 각 배열에는 기본 바이트 순서로 유니 코드 문자가 포함됩니다.

2) 정수에 문자 값을 할당하면 16 비트 유니 코드 문자 코드가 동등한 정수로 변환됩니다. 따라서 U + 0063 인 'c'0x0063 또는 99가됩니다.

3) 각 String은 객체이므로 클래스 멤버 (예 : 클래스 설명자 단어, 잠금/세마포어 단어 등) 이외의 정보가 포함되어 있습니다.

ADENDUM
내용은 (각 객체와 관련된 고유의 오버 헤드를 결정한다)이 JVM 구현에 의존 오브젝트 및 클래스는 실제로 부호화하는 방법 (즉, 일부 라이브러리는 다른 것보다 더 효율적일 수있다).


객체 인스턴스 당 두 단어의 오버 헤드를 할당하는 전형적인 구현 (클래스 기술자/포인터, 및 세마포어/잠금 제어 워드); String 오브젝트는 길이가 int이고 배열 참조가 char[]입니다. 문자열의 실제 문자 내용은 제 2 대상물에 저장되고, 차례로 두 개의 단어를 분배 char[] 배열 플러스 배열 길이 워드 더한만큼 16- 비트 char 요소 문자열을 위해 필요에 따라 (플러스 불필요한 문자 문자열이 생성되었을 때 주위에 매달려있었습니다).

부칙 2
하나 문자가 하나 유니 코드 문자를 나타내는 경우 대부분의 경우에만 해당됩니다. 이것은 UCS-2 인코딩을 의미하고 2005 년 이전에는 true입니다. 그러나 지금까지는 유니 코드가 커졌고 문자열은 UTF-16을 사용하여 인코딩되어야합니다. 단 하나의 유니 코드 문자가 char을 Java String에 사용할 수 있습니다.

Apache의 구현을위한 실제 소스 코드를 살펴보십시오. 에서 :
http://www.docjar.com/html/api/java/lang/String.java.html

+0

실제로 3) 부분에서 무엇을 말하려고합니다. 그것은 다른 정보를 포함하므로 .... ?? –

+0

"문자 값을 정수에 할당하면 16 비트 유니 코드 문자 코드가 해당 정수로 변환됩니다." 여기서 약간 혼란스러운 점은 Unicode 인코딩이 처음 256 자의 ASCII와 일치한다는 것입니다. 유니 코드는 처음 256 자에 대해 확장 ASCII (8 비트)와 상호 연관됩니다. 확장 ASCII는 첫 번째 128 비트에 대해 7 비트 ASCII와 직접적으로 대응합니다. 따라서 'c'는 유니 코드, 확장 ASCII 및 ASCII에서 0x63으로 인코딩됩니다. 이것이 'c'에 대한 int를보고 ASCII라고 생각하는 이유입니다 (sortof는 :). –

+0

@HawkeyeParker : 예, 7 비트 ASCII (ISO 646) 및 8 비트 ISO 8859-1 (Latin-1)은 유니 코드의 적절한 하위 집합입니다. 즉, Java는 모든 문자 값을 16 비트 유니 코드로 인코딩합니다. –

29
  1. Java는 문자열을 내부적으로 UTF-16으로 저장합니다.

  2. "기본 인코딩"은 적절하지 않습니다. Java는 문자열을 내부적으로 UTF-16으로 저장하지만 외부에서 사용되는 인코딩 인 "시스템 기본 인코딩"은 플랫폼에 따라 다르며 일부 플랫폼에서는 환경 변수와 같은 것으로도 변경할 수 있습니다.

    ASCII는 유니 코드의 하위 집합 인 라틴어 1의 하위 집합입니다. UTF-16은 유니 코드를 인코딩하는 방법입니다. 따라서 ASCII 범위에 속하는 문자에 대해 int i = 'x' 테스트를 수행하면 ASCII 값을 얻게됩니다. 그러나 UTF-16은 ASCII보다 훨씬 많은 문자를 나타낼 수 있습니다. java.lang.Character docs에서

  3. :

    자바 2 플랫폼은 문자 배열과 문자열과 StringBuffer를 클래스에서 UTF-16 표현을 사용합니다.

    그래서이 클래스에는 UTF-16이 사용되는 Java 2 플랫폼의 일부로 정의됩니다.

+0

char 및 char 배열의 사용은 public, external API String 및 StringBuffer의 경우. 문자의 내부 저장은 구현에 따라 다릅니다. – jarnbjo

+0

@jarnbjo 위의 내용은 문서에서 직접 인용 한 것입니다. Java에서'char' 데이터 유형은 UTF-16 코드 단위 (문자가 아니라 유니 코드 코드 포인트)를 나타냅니다. 따라서 자바의 텍스트 표현은 UTF-16이라고 말하는 것이 안전하다고 생각합니다. 그렇습니다. 구현시 커버 아래에서 다른 것을 수행 할 수도 있지만 결국 UTF-16을 사용하는 것처럼 보이게해야합니다. –

+0

String 및 StringBuffer 클래스의 내부 저장소에 액세스 할 수있는 방법이 없으므로 인용 한 문이 해당 클래스에 적용된다고 가정하는 것이 합리적입니다. – jarnbjo

2

이 질문에 답하지는 않지만 주목할 가치가 있습니다 ... 자바 바이트 코드 (클래스 파일)에서 문자열은 UTF-8로 저장됩니다. http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html

+1

OP는'.class' 파일 형식이 아니라 메모리 내 저장소에 대해 질문했습니다. –

+1

@Loadmaster 나는 그것이 유용한 정보라는 것을 믿는다. 그리고 나는 그것이 클래스 파일이라는 것을 분명히 언급한다 - 그래서 당신의 문제는 무엇인가? – Ralph

+1

하지만 질문에 대답하지 않습니다. 당신은 코멘트로 그것을 게시 할 수 있고 "이것이 당신의 질문에 대답하지 않는 동안 그것은 주목할 가치가 있습니다 ..."이것은 정말로 유용한 정보이지만, UTF- 8. 점은 무엇인가? 이것은 JVM이 시작시 모든 문자열을 UTF-16으로 변환해야 함을 의미합니다. –

1

편집 : 덕분에 내 대답 :

1) 모든 내부 문자열 처리가 UTF-16에서 이루어집니다를 수정 나를 도와 LoadMaster합니다.

2) ASCII는 UTF-16의 하위 집합입니다.

3) Java에서 내부적으로 UTF-16입니다. 나머지는 네가 어디에 있느냐에 따라 달라진다.

+2

문자열은 내부적으로 (메모리 내에서) char []로 저장됩니다. 각 요소는 16 비트 UTF-16 유니 코드 문자를 포함합니다. UTF-8은 문자열을 내부적으로 저장하는 데 사용되지 않지만 I/O 스트림을 문자열로 변환하거나 문자열에서 변환하는 데 사용됩니다. –

+0

@LoadMaster : 시간이 지남에 변경 되었습니까? Java는 항상 내부적으로 UTF-16이었습니다. – LaGrandMere

+0

예,'String'은 항상 내부 문자'char []'를 사용하여 문자 값을 저장합니다. –

관련 문제