Что такое кодировка символов String в Java?
Я действительно запутался в отношении кодирования строк в Java. У меня есть несколько вопросов. Пожалуйста, помогите мне, если вы знаете ответ на них:
1) Какова внутренняя кодировка строк Java в памяти? Когда я пишу String a = "Hello"
, в каком формате он будет сохранен? Поскольку Java является независимой от машины, я не думаю, что система выполнит кодировку.
2) Я прочитал в сети, что "UTF-16" является кодировкой по умолчанию, но я запутался, потому что, когда я пишу, что int a = 'c'
, я получаю номер символа в таблице ASCII. Точно так же ASCII и UTF-16?
3) Также я не был уверен в том, что зависит от хранения строки в памяти: OS, language?
Ответы
Ответ 1
1) Строки - это объекты, которые обычно содержат массив char
и длину строк. Массив символов обычно реализуется как непрерывный массив из 16-битных слов, каждый из которых содержит символ Unicode в собственном порядке байтов.
2) Назначение символьного значения целому числу преобразует 16-разрядный код символа Юникода в его целочисленный эквивалент. Таким образом, 'c'
, которое равно U + 0063, становится 0x0063
, или 99.
3) Поскольку каждый String
является объектом, он содержит другую информацию, кроме своих членов класса (например, слово дескриптора класса, слово блокировки/семафора и т.д.).
ADENDUM
Содержимое объекта зависит от реализации JVM (которая определяет присущие служебные данные, связанные с каждым объектом), и того, как класс фактически кодируется (то есть некоторые библиотеки могут быть более эффективными, чем другие).
Пример
Типичная реализация распределит накладные расходы на два слова на экземпляр объекта (для дескриптора класса/указателя и слова управления семафором/блокировкой); a String
объект также содержит ссылку int
length и a char[]
. Фактическое содержимое символа строки сохраняется во втором объекте, массиве char[]
, который, в свою очередь, выделяется двумя словами, плюс слово длины массива, плюс столько же 16-разрядных элементов char
, сколько необходимо для строки ( плюс любые дополнительные символы, которые оставались зависающими, когда была создана строка).
ДОБАВЛЕНИЕ 2
Случай, когда один char представляет один символ Юникода, имеет значение только в большинстве случаев. Это означало бы UCS-2 кодировку и true до 2005 года. Но к настоящему времени Unicode стал больше, а строки должны быть закодированы с использованием UTF-16 - - где, увы, один символ Unicode может использовать два char
в Java String
.
Взгляните на фактический исходный код для реализации Apache, например. at:
http://www.docjar.com/html/api/java/lang/String.java.html
Ответ 2
-
Java хранит строки как UTF-16 внутренне.
-
"кодировка по умолчанию" не совсем правильная. Java хранит строки как UTF-16 внутренне, но используемая внешняя кодировка, "системная кодировка по умолчанию", варьируется от платформы к платформе и даже может быть изменена такими вещами, как переменные среды на некоторых платформах.
ASCII - это подмножество Latin 1, которое является подмножеством Unicode. UTF-16 является способом кодирования Unicode. Поэтому, если вы выполните тест int i = 'x'
для любого символа, который попадает в диапазон ASCII, вы получите значение ASCII. Однако UTF-16 может представлять намного больше символов, чем ASCII.
-
Из java.lang.Character docs:
Платформа Java 2 использует представление UTF-16 в массивах char и в классах String и StringBuffer.
Таким образом, он определен как часть платформы Java 2, для которой UTF-16 используется для этих классов.
Ответ 3
Пока это не отвечает на ваш вопрос, стоит отметить, что... В java-байтовом коде (файле класса) строка хранится в UTF-8. http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
Ответ 4
Изменить: спасибо LoadMaster за помощь в исправлении моего ответа:)
1) Вся внутренняя обработка строк выполняется в UTF-16.
2) ASCII - это подмножество UTF-16.
3) Внутренне в Java есть UTF-16. Для остальных это зависит от того, где вы находитесь, да.