Java获取字符

时间:2017-03-01 22:14:11

标签: java unicode encoding character-encoding ascii

我有以下代码打印出来自字符串s0s1的字节;输出结果被评论:

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

但我仍然没有得到的是s0s1字符串之间的区别。在这两种情况下,我都要求来自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

3 个答案:

答案 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 0b111010110xEB的代表。