如果我将UTF-8 char转换为byte,那么基于语言环境,环境等的这3个实现的结果是否会有所不同?
byte a = "1".getBytes()[0];
byte b = "1".getBytes(Charset.forName("UTF-8"))[0];
byte c = '1';
答案 0 :(得分:4)
您的第一行 依赖于环境,因为它会使用系统的默认字符编码对字符串进行编码,该编码可能是UTF-8,也可能不是。{/ p>
无论系统的区域设置或默认字符编码是什么,您的第二行始终会产生相同的结果。它将始终使用UTF-8对字符串进行编码。
请注意,UTF-8是一种可变长度的字符编码。只有前127个字符在一个字节中编码;所有其他字符将占用2到6个字节。
您的第三行将char
投射到int
。这将导致int
包含字符的UTF-16字符代码,因为Java char
使用UTF-16存储字符。由于UTF-16以与UTF-8相同的方式对字符进行部分编码,因此结果将与第二行相同,但对于任何字符通常都不是这样。
答案 1 :(得分:1)
原则上这个问题已经得到了回答,但我无法抗拒发布一些涂鸦,对于那些喜欢玩代码的人来说:
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);
}
}
}
如果你这样做,例如用:
java -Dfile.encoding="UTF-16LE" EncodingTest
你将得不到输出。 但是当然,如果你尝试的话,每个字节(好的,第一个除外)都是错的:
java -Dfile.encoding="UTF-16BE" EncodingTest
因为&#34; big endian&#34;对于ascii字符,第一个字节始终为零。
这是因为在UTF-16中,ascii字符'\u00xy
由两个字节表示,UTF16-LE表示为[xy, 0]
,UTF16-BE表示为[0, xy]
但是只有第一个语句产生任何输出,因此b
和c
对于前127个ascii字符确实相同 - 因为在UTF-8中它们由单个字节编码。但是,对于任何其他角色来说,情况并非如此;它们都有UTF-8中的多字节表示。