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) является самым быстрым.
- https://gist.github.com/amarkevich/e3c27435c923d8430b66c6c2e28d4953