Java 单个UTF-8字符到字节

Java 单个UTF-8字符到字节,java,Java,如果我将UTF-8字符转换为字节,这3种实现的结果是否会因区域设置、环境等而有所不同 byte a = "1".getBytes()[0]; byte b = "1".getBytes(Charset.forName("UTF-8"))[0]; byte c = '1'; 第一行取决于环境,因为它将使用系统的默认字符编码对字符串进行编码,这可能是,也可能不是 无论系统的区域设置或默认字符编码是什么,第二行始终会产生相同的结果。它将始终使用UTF-8对字符串进行编码 请注意,UTF-8是一种可变

如果我将UTF-8字符转换为字节,这3种实现的结果是否会因区域设置、环境等而有所不同

byte a = "1".getBytes()[0];
byte b = "1".getBytes(Charset.forName("UTF-8"))[0];
byte c = '1';

第一行取决于环境,因为它将使用系统的默认字符编码对字符串进行编码,这可能是,也可能不是

无论系统的区域设置或默认字符编码是什么,第二行始终会产生相同的结果。它将始终使用UTF-8对字符串进行编码

请注意,UTF-8是一种可变长度字符编码。只有前127个字符编码在一个字节中;所有其他字符将占用2到6个字节


第三行将
char
转换为
int
。这将导致
int
包含字符的UTF-16字符代码,因为Java
char
使用UTF-16存储字符。由于UTF-16以与UTF-8相同的方式对字符进行部分编码,因此结果与第二行相同,但对于任何字符来说,这通常都是不正确的。

原则上,这个问题已经得到了回答,但对于那些喜欢玩代码的人,我忍不住要发表一些涂鸦:

import java.nio.charset.Charset;

public class EncodingTest {

    private static void checkCharacterConversion(String c) {
        byte asUtf8 = c.getBytes(Charset.forName("UTF-8"))[0];
        byte asDefaultEncoding = c.getBytes()[0];
        byte directConversion = (byte)c.charAt(0);
        if (asUtf8 != asDefaultEncoding) {
            System.out.println(String.format(
                "First char of %s has different result in UTF-8 %d and default encoding %d",
                c, asUtf8, asDefaultEncoding));
        }
        if (asUtf8 != directConversion) {
            System.out.println(String.format(
                "First char of %s has different result in UTF-8 %d and direct as byte %d",
                c, asUtf8, directConversion));
        }
    }

    public static void main(String[] argv) {

       // btw: first time I ever wrote a for loop with a char - feels weird to me
       for (char c = '\0'; c <= '\u007f'; c++) {
           String cc = new String(new char[] {c});
           checkCharacterConversion(cc);
       }
    }
}
您将无法获得任何输出。 当然,如果您尝试以下操作,每个字节(ok,第一个除外)都会出错:

java -Dfile.encoding="UTF-16BE"  EncodingTest
因为在“big-endian”中,ascii字符的第一个字节始终为零。 这是因为在UTF-16中,ascii字符
'\u00xy
由两个字节表示,在UTF16-LE中表示为
[xy,0]
,在UTF16-BE中表示为
[0,xy]


但是,只有第一条语句产生任何输出,因此前127个ascii字符的
b
c
实际上是相同的,因为在UTF-8中,它们是由单个字节编码的。然而,这对于任何其他角色都是不正确的;它们在UTF-8中都有多字节表示。

绝对如此。尝试“UTF-16值大于127的任何字符”。既然有超过255个字符,您怎么可能期望将
char
转换为
byte
,而不丢失信息呢?@JonSkeet那么,仅前127个字符如何?
java -Dfile.encoding="UTF-16BE"  EncodingTest