Java String.getBytes(charsetName) vs String.getBytes(объект Charset)

Мне нужно закодировать массив String в байтах, используя кодировку UTF-8. Я использую Google guava, он имеет класс Charsets, который уже определяет экземпляр Charset для кодировки UTF-8. У меня есть 2 способа сделать:

  • String.getBytes(charsetName)

    try {        
        byte[] bytes = my_input.getBytes ( "UTF-8" );
    } catch ( UnsupportedEncodingException ex) {
    
    }
    
  • String.getBytes(объект Charset)

    // Charsets.UTF_8 is an instance of Charset    
    
    byte[] bytes = my_input.getBytes ( Charsets.UTF_8 );
    

Мой вопрос - какой из них я должен использовать? Они возвращают тот же результат. Для пути 2 - мне не нужно ставить try/catch! Я смотрю на исходный код Java, и я вижу, что путь 1 и путь 2 выполняются по-разному.

У кого-нибудь есть идеи?

Ответы

Ответ 1

Если вы собираетесь использовать строковый литерал (например, "UTF-8" ), вы не должны. Вместо этого используйте вторую версию и поставьте постоянное значение StandardCharsets (в частности, StandardCharsets.UTF_8, в этом случае).

Первая версия используется, когда кодировка является динамической. Это будет иметь место, когда вы не знаете, что кодировка находится во время компиляции; он предоставляется конечным пользователем, считывается из файла конфигурации или системного свойства и т.д.

Внутри, оба метода вызывают версию StringCoding.encode(). Первая версия encode() просто ищет имя Charset по указанному им имени и бросает исключение, если эта кодировка неизвестна/недоступна.

Ответ 2

Первый API предназначен для ситуаций, когда вы не знаете кодировку во время компиляции; второй - для ситуаций, когда вы это делаете. Поскольку кажется, что ваш код нуждается в UTF-8, вы должны предпочесть второй API:

byte[] bytes = my_input.getBytes ( Charsets.UTF_8 ); // <<== UTF-8 is known at compile time

Первый API предназначен для ситуаций, когда кодировка поступает извне вашей программы - например, из файла конфигурации, с пользовательского ввода, как часть клиентского запроса на сервер и т.д. Вот почему из него выбрано исключенное исключение - для ситуаций, когда кодировка, указанная в конфигурации или с помощью некоторых других средств, недоступна.

Ответ 3

Так как они возвращают один и тот же результат, вы должны использовать метод 2, потому что он обычно более безопасен и более эффективен, чтобы не просить библиотеку разбираться и, возможно, прерывать строку, предоставленную пользователем. Кроме того, избегая попыток захвата, вы также очистите свой собственный код.

Charsets.UTF_8 можно более легко проверить во время компиляции, что, скорее всего, является причиной того, что вам не нужен try-catch.

Ответ 4

Если у вас уже есть Charset, используйте вторую версию, поскольку она меньше подвержена ошибкам.

Ответ 5

Я согласился с ответом Брайана, но производительность зависит от реализации. Существует тест [1] для разных случаев, который показывает, что String.getBytes(String) является самым быстрым.

  1. https://gist.github.com/amarkevich/e3c27435c923d8430b66c6c2e28d4953