Собственный набор символов Java для строк - PullRequest
0 голосов
/ 04 июня 2018

Я совершенно сбит с толку ответами, которые я видел на stackoverflow плюс на java docs

Хотя вся теория в документах и ​​стеке по ссылкам выше, кажется, указывает на то, что UTF-16 является собственным набором символов, поддерживаемым Java,есть другая теория, которая говорит, что это зависит от JVM / OS, например, в этой ссылке говорится:

Каждый экземпляр виртуальной машины Java имеет кодировку по умолчанию, которая можетили не может быть одним из стандартных кодировок.Набор символов по умолчанию определяется во время запуска виртуальной машины и обычно зависит от языкового стандарта и набора символов, используемых базовой операционной системой.

Затем в той же ссылке в другом разделе написано

Нативная кодировка символов языка программирования Java - UTF-16.

Мне трудно понять это явно противоречащее утверждение как:

  • один говорит, что это зависит от ОС
  • другой (я делаю вывод)говорит, что независимо от операционной системы UTF-16 является кодировкой для Java (это также то, что говорят все ссылки, которые я упомянул выше)

Опять же, теперь, когда я выполняю следующий фрагменткод:

package org.sheel.classes;

import java.nio.charset.Charset;

public class Test {

    public static void main(String[] args) {
         System.out.println(Charset.defaultCharset());
    }

}

... в онлайн-редакторе я вижу UTF-8.В моей локальной системе я вижу windows-1252

И, наконец, есть предложение по улучшению JDK ( JEP ), в котором говорится об изменении значения по умолчанию на UTF-8

* 1045.* Может ли быть объяснение этой путаницы?

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Внутренняя кодировка, используемая 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 гарантирует, что каждый символ будет сохранен.

0 голосов
/ 04 июня 2018

Внутренняя строка - это массив символов, toCharArray(), каждый из которых представляет собой кодовую точку utf-16.Когда вы преобразуете строку в массив байтов без указания набора символов, getBytes(), используется ОС 1.

PS: как отмечалось в VGR, последние реализации могут не хранить String в виде массива char, нокак программисты мы обычно взаимодействуем, используя символы, которые всегда имеют UTF-16.

...