String s = new String(s.getBytes(“ UTF-8”),“ UTF-8”);之间的区别是什么?和String s = new String(s.getBytes(),“ UTF-8”);

时间:2019-01-15 12:06:23

标签: java

有什么区别
String(s.getBytes("UTF-8"),"UTF-8"); 

String(s.getBytes(),"UTF-8");

在第一个代码示例中,一些特殊字符被解码了,为什么?有什么区别?

如果我对UTF-8使用双重解码会不会有什么影响?

3 个答案:

答案 0 :(得分:5)

来自javadoc

对于getBytes()

  

使用平台的默认字符集将此字符串编码为字节序列,并将结果存储到新的字节数组中。

getBytes(Charset)说:

  

使用给定的字符集将此字符串编码为字节序列,并将结果存储到新的字节数组中。

因此,第二个版本允许您完全控制,第一个调用依赖于该平台的默认字符集。

这就是全部。

有关该“默认平台”,请参见here。并且请注意,人们要求将默认值设置为全部都是UTF-8(请参见here)。

答案 1 :(得分:3)

因此,您要询问以下两行:

main()

这两条线都没有做任何有用的事情。第2行甚至比第1行还差;它可能不仅没有用,而且还会出错,具体取决于系统的默认字符编码是什么。

第1行实际上什么也没做。它使用UTF-8字符编码将字符串 import ( "fmt" "io" "log" "os" "os/exec" ) var pager io.WriteCloser func main() { var cmd *exec.Cmd cmd, pager = runPager() defer func() { pager.Close() cmd.Wait() }() fmt.Fprintln(pager, "Hello, 世界") } func runPager() (*exec.Cmd, io.WriteCloser) { pager := os.Getenv("PAGER") if pager == "" { pager = "more" } cmd := exec.Command(pager) out, err := cmd.StdinPipe() if err != nil { log.Fatal(err) } cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { log.Fatal(err) } return cmd, out } 编码为字节,然后立即使用UTF-8将字节解码回字符串。字符串String s1 = new String(s.getBytes("UTF-8"), "UTF-8"); // line 1 String s2 = new String(s.getBytes(), "UTF-8"); // line 2 将始终与原始字符串完全相同;编码和解码就没用了。

第2行的功能取决于系统上使用的默认字符编码。如果默认字符编码为UTF-8,则其与第1行完全相同。如果它与UTF-8不同,则将得到错误解码的字符串。

假设系统的默认字符编码为ISO-8859-1。然后,第2行使用ISO-8859-1对字符串进行编码,然后立即对结果进行解码,就好像它是UTF-8一样-这是错误的。您可能会得到一个字符串,其中包含错误解码的字符,甚至是异常。

阅读您正在使用的方法的API文档,以了解它们的确切作用:

答案 2 :(得分:1)

问题中包含的两个例子都是胡说八道。

Java String作为UTF-16代码点的数组存储在内存中。 现在将byte[]标识为UTF-8代码点数组为时已晚 表示数组已经转换为字符串,

如果您收到一个byte []并想将其存储为String, 那么这样做很有意义:

//assume input byte[] kapow
String blammy = new String(kapow, StandardCharsets.UTF_8);

如果您有一个String值,并想将其作为字节写到某处[] 使用UTF-8编码, 那么这很有意义

// assume input String blammy 
byte[] kapow = blammy.getBytes(StandardCharsets.UTF_8);

请注意,在两种情况下,我都使用了该方法的(blah,Charset)版本。 做这个。 (blah,“ UTF-8”)版本会引发一个已检查的异常。 (空白,Charset)版本永远不会引发异常,而StandardCharsets类会这样做(从StandardCharsets JavaDoc页面):

  

标准字符集的常量定义。这些字符集保证可以在Java平台的每种实现中使用。