Подтвердить что ты не робот

Почему Java String.getBytes() использует "ISO-8859-1"

из java.lang.StringCoding:

String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;

Это то, что используется в Java.lang.getBytes(), в linux jdk 7 Мне всегда казалось, что UTF-8 является кодировкой по умолчанию?

Спасибо

4b9b3361

Ответ 1

Это немного сложно...

Java пытается использовать кодировку символов по умолчанию для возврата байтов с помощью String.getBytes().

  • Кодировка по умолчанию предоставляется с помощью свойства system file.encoding.
  • Это кэшируется, и нет смысла изменять его с помощью System.setProperty(..) после запуска JVM.
  • Если свойство file.encoding не сопоставляется с известной кодировкой, то указывается UTF-8.

.... Вот сложная часть (которая, вероятно, никогда не войдет в игру)....

Если система не может декодировать или кодировать строки с использованием кодировки по умолчанию (UTF-8 или другой), тогда будет отказ от ISO-8859-1. Если резервное копирование не работает... система не сработает!

.... Действительно... (gasp!)... Может ли это сбой, если моя указанная кодировка не может быть использована, а UTF-8 или ISO-8859-1 также непригодны для использования?

Да. Исходные комментарии Java ссылаются на метод StringCoding.encode(...):

//Если мы не можем найти ISO-8859-1 (требуемая кодировка), то с установкой все серьезно ошибочно.

... и затем он вызывает System.exit(1)


Итак, почему существует намеренный отказ от ISO-8859-1 в методе getBytes()?

Возможно, хотя и не вероятно, что JVM-пользователи могут не поддерживать декодирование и кодирование в UTF-8 или кодировку, указанную при запуске JVM.

Затем используется ли по умолчанию кодировка по умолчанию в классе String во время getBytes()?

Нет. Однако лучший вопрос - это...


Предоставляет ли String.getBytes() то, что он promises?

Контракт, определенный в Javadoc, верен.

Поведение этого метода, когда эта строка не может быть закодирована в default charset не указан. Класс CharsetEncoder должен быть используется, когда требуется больше контроля над процессом кодирования.


Хорошие новости (и лучший способ сделать что-то)

Всегда рекомендуется указывать "ISO-8859-1" или "US-ASCII" или "UTF-8" или любой другой набор символов, который вы хотите использовать при преобразовании байтов в строки "наоборот" - если только вы не ранее получили кодировку по умолчанию и сделали 100% уверенным, что это тот, который вам нужен.

Используйте этот метод вместо:

public byte[] getBytes(String charsetName)

Чтобы найти значение по умолчанию для вашей системы, просто используйте:

Charset.defaultCharset()

Надеюсь, что это поможет.

Ответ 2

Без параметров String.getBytes() метод по умолчанию не использует ISO-8859-1. Он будет использовать кодировку платформы по умолчанию, если это можно определить. Если, однако, это либо отсутствует, либо является непризнанной кодировкой, оно возвращается к ISO-8859-1 как "по умолчанию по умолчанию".

Вы должны очень редко видеть это на практике. Обычно стандартное кодирование платформы будет обнаружено правильно.

Однако я настоятельно рекомендую вам указать явное кодирование символов каждый раз, когда вы выполняете операцию кодирования или декодирования. Даже если вы хотите использовать платформу по умолчанию, укажите это явно.

Ответ 3

Что по соображениям совместимости.

Исторически, все java-методы в Windows и Unix, не определяющие кодировку, использовали общий в то время, то есть "ISO-8859-1".

Как упоминалось Isaac и javadoc, используется кодировка платформы по умолчанию (см. Charset.java):

594    public static Charset defaultCharset() {
595        if (defaultCharset == null) {
596            synchronized (Charset.class) {
597                String csn = AccessController.doPrivileged(
598                    new GetPropertyAction("file.encoding"));
599                Charset cs = lookup(csn);
600                if (cs != null)
601                    defaultCharset = cs;
602                else
603                    defaultCharset = forName("UTF-8");
604            }
605        }
606        return defaultCharset;
607    }

Всегда указывать кодировку при выполнении строки в байтах или байтах для преобразования строк.

Даже если, как и в случае String.getBytes(), вы все равно находите не устаревший метод, не принимающий кодировку (большинство из них были устаревшими при появлении Java 1.1). Точно так же, как и с контентом, формат платформы не имеет значения, что актуально для нормы формата хранения.

Ответ 4

Разработайте ответ на Skeet (который, конечно, правильный)

В java.lang.String source getBytes() вызывает StringCoding.encode(char[] ca, int off, int len), который имеет в своей первой строке:

String csn = Charset.defaultCharset().name();

Затем (не сразу, но абсолютно) он вызывает static byte[] StringEncoder.encode(String charsetName, char[] ca, int off, int len), куда приходит строка, которую вы цитируете, - передавая как charsetName csn - поэтому в этой строке charsetName будет будет кодировка по умолчанию если он существует.