Внутренняя кодировка, используемая String, не имеет ничего общего с кодировкой платформы по умолчанию.Они полностью независимы друг от друга.
Внутренние строки
Внутри строки строка может хранить свои данные как угодно.Как программисты, мы не взаимодействуем с частной реализацией;мы можем использовать только публичные методы.Публичные методы обычно возвращают данные String в виде UTF-16 (char
значения), хотя некоторые, например, codePoints () метод , могут возвращать полные значения UTF-32 int.Ни один из этих методов не указывает, как данные String хранятся внутри, только формы, в которых программист может проверять эти данные.
Таким образом, вместо того, чтобы говорить, что String хранит данные внутри как UTF-16 или любая другая кодировка, этоправильно сказать, что String хранит последовательность кодовых точек Unicode и делает их доступными в различных формах, чаще всего в виде значений символов.
Набор символов по умолчанию
Набор символов по умолчанию - это то, что Java получает избазовая система.
Как указал Роберто, кодировка по умолчанию имеет значение, когда вы используете определенные (устаревшие) методы и конструкторы.Преобразование строки в байты или преобразование байтов в строку без явного указания набора символов будет использовать набор символов по умолчанию.Точно так же при создании InputStreamReader или OutputStreamWriter без указания набора символов будет использоваться набор символов по умолчанию.
Обычно неразумно полагаться на набор символов по умолчанию, так как код будет работать по-разному на разных платформах.Кроме того, некоторые наборы символов могут представлять все известные символы, но некоторые наборы символов могут представлять только небольшое подмножество всего репертуара Unicode.В частности, Windows обычно имеет кодировку по умолчанию, которая использует один байт для представления каждого символа (windows-1252
в американских версиях Windows), и, очевидно, этого недостаточно для хранения сотен тысяч доступных символов.
Если вы полагаетесь на кодировку по умолчанию, действительно есть вероятность, что вы потеряете информацию:
String s = "\u03c0\u22603"; // "π≠3"
byte[] bytes = s.getBytes();
for (byte b : bytes) {
System.out.printf("%02x ", b);
}
System.out.println();
В большинстве систем будет напечатано:
cf 80 e2 89 a0 33
В Windows,вероятно, будет напечатано:
3f 3f 33
Символы pi и неравные символы не представлены в кодировке windows-1252, поэтому в Windows метод getBytes заменяет их на вопросительные знаки (значение байта 3f).
Если преобразование в или из байтов не используется, объекты String никогда не потеряют информацию, потому что независимо от того, как они хранят свои данные внутри, класс String гарантирует, что каждый символ будет сохранен.