【问题标题】:Java String.getBytes( charsetName ) vs String.getBytes ( Charset object )Java String.getBytes(charsetName) vs String.getBytes(Charset object)
【发布时间】:2014-06-12 13:30:58
【问题描述】:

我需要使用 UTF-8 编码将字符串编码为字节数组。我正在使用 Google guava,它的 Charsets 类已经为 UTF-8 编码定义了 Charset 实例。我有两种方法:

  1. String.getBytes(charsetName)

    try {        
        byte[] bytes = my_input.getBytes ( "UTF-8" );
    } catch ( UnsupportedEncodingException ex) {
    
    }
    
  2. String.getBytes(字符集对象)

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

我的问题是我应该使用哪一个?它们返回相同的结果。对于方式 2 - 我不必尝试/捕获!我看了一下 Java 源代码,发现方式 1 和方式 2 的实现方式不同。

有人有什么想法吗?

【问题讨论】:

  • 两者的结果是否相同?如果是这样,我会赞成后一种情况。如果不是,您需要决定哪个是正确的。
  • 是的,它们返回相同的结果。但我担心的是为什么它们的实施方式不同?为什么方式 1 不会在内部调用方式 2?
  • @Loc 是什么让您认为前者没有在内部调用后者? (或者,他们都不会调用其他一些常见的内部方法?)docjar.com/html/api/java/lang/String.java.html 第 951 - 980 行
  • @BrianRoach Roach 他们调用 StringCoding.encode 但方式 1 调用此方法的第一个参数是 String,方式 2 调用此方法的第一个参数是 Charset 实例。如果我们看一下这个方法(第 2 版),它们的实现方式不同。

标签: java string character-encoding


【解决方案1】:

如果您要使用字符串文字(例如“UTF-8”)......您不应该这样做。而是使用第二个版本并提供来自StandardCharsets 的常量值(具体而言,在本例中为StandardCharsets.UTF_8)。

当字符集是动态时使用第一个版本。当您在编译时不知道字符集是什么时,就会出现这种情况;它由最终用户提供,从配置文件或系统属性等中读取。

在内部,这两种方法都调用了StringCoding.encode() 的一个版本。 encode() 的第一个版本只是首先通过提供的名称查找 Charset,如果该字符集未知/不可用则抛出异常。

【讨论】:

  • 没有。在内部,它们调用 StringCoding.encode(),但有两个版本的 StringCoding.encode()。方式一调用这个方法第一个参数是charsetName,方式二调用这个方法第一个参数是Charset实例。 2 版本的 StringCoding.encode() 实现方式不同。我不知道为什么。
  • 抱歉,我将进行编辑以澄清 - 查找发生在 encode()
【解决方案2】:

第一个 API 用于在编译时不知道字符集的情况;第二个是针对您这样做的情况。由于您的代码似乎特别需要 UTF-8,因此您应该更喜欢第二个 API:

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

第一个 API 适用于当字符集来自您的程序外部的情况 - 例如,来自配置文件、来自用户输入、作为客户端请求到服务器的一部分,等等.这就是为什么会抛出一个检查异常的原因 - 对于配置中指定的字符集或通过其他方式指定的字符集不可用的情况。

【讨论】:

    【解决方案3】:

    由于它们返回相同的结果,您应该使用方法 2,因为它通常更安全、更有效地避免要求库解析并可能破坏用户提供的字符串。此外,避免 try-catch 也会使您自己的代码更清晰。

    Charsets.UTF_8 可以在编译时更容易地检查,这很可能是您不需要try-catch 的原因。

    【讨论】:

      【解决方案4】:

      如果您已经拥有 Charset,请使用第二个版本,因为它不易出错。

      【讨论】:

        猜你喜欢
        • 2016-02-14
        • 1970-01-01
        • 1970-01-01
        • 2014-05-16
        • 1970-01-01
        • 2012-11-12
        • 2012-09-21
        • 2021-04-26
        • 1970-01-01
        相关资源
        最近更新 更多