我有以下代码打印出来自字符串s0
和s1
的字节;输出结果被评论:
public static void main(String[] args) throws UnsupportedEncodingException {
String s0="H\u00ebllo";
String s1="Hëllo";
byte[] bytes=s0.getBytes("ISO8859_1"); //72 -21 108 108 111
//byte[] bytes=s1.getBytes("ISO8859_1"); //72 -61 -85 108 108 111
//byte[] bytes=s0.getBytes("UTF-8"); //72 -61 -85 108 108 111
//byte[] bytes=s1.getBytes("UTF-8"); //72 -61 -125 -62 -85 108 108 111
for (int i=0, i<bytes.length; i++) {
System.out.println(bytes[i]);
}
}
我不明白的是这些数字的来源。如果所有字符代码都是正数,为什么会出现负数?为什么第二种情况下有6个数字?使用Unicode表示法与文字表示时,为什么ë
字符的数字不同?
修改:
据我所知,这些数字首先被转换为无符号数字:
ë(ISO8859_1) = 0xeb = 235 = 11101011 = -21 (two's complement for signed numbers)
ë (UTF-8) = 0xc3 0xab => 0xc3 = 195 = 11000011 = -61, 0xab = 171 = 10101011 = -85
但我仍然没有得到的是s0
和s1
字符串之间的区别。在这两种情况下,我都要求来自ISO8859_1
的{{1}}字节,而在第二种情况下,我仍然会得到getBytes()
的字节。
修改
UTF-8
导致此输出:
byte[] bytes=s1.getBytes("UTF-8");
我真的很困惑。
修改:
72 -61 -125 -62 -85 108 108 111
两者都给System.out.println(System.getProperty("file.encoding"));
System.out.println(java.nio.charset.Charset.defaultCharset());
。源文件位于UTF-8
。
答案 0 :(得分:3)
字节是Java中的带符号数字,范围在-128到127.第二种情况下有6个数字,因为源文件使用UTF-8编码,Java编译器假定特定于平台的编码可能不是UTF -8。使用IDE时,查找与源和/或编译器编码相对应的设置。使用javac
进行编译时,请尝试指定-encoding UTF-8
。
答案 1 :(得分:2)
在Java中,byte
基元类型为signed
,这意味着范围从-128到+127(第一位被认为是数字的符号)。
在扩展ASCII和其他8位编码(如ISO-8859-1)中,存在字节值大于127的字符。当打印为标准Java byte
时,这些字符将显示为负数。
如果您使用的是UTF-8(或其他Unicode UTF编码),则非ASCII字符由2-4个字节表示,并且它们中的每一个都可能“大于127”,因此它们将显示为只需将它们打印为byte
值即可为负数。
答案 2 :(得分:0)
在java中,所有数字类型都是签名(与unsigned相对)。请注意,char
不是数字类型,即使它可以在算术上使用(滥用)。
您的编码提供的-21
只是Java byte
0b11101011
或0xEB
的代表。