我即将开始处理需要读取字节和创建字符串的事情。正在读取的字节表示UTF-16字符串。所以只是为了测试我想要将UTF-16编码的简单字节数组转换为字符串。数组中的前2个字节必须表示字节序,因此必须是0xff 0xfe或0xfe 0xff。所以我尝试按如下方式创建我的字节数组:
byte[] bytes = new byte[] {0xff, 0xfe, 0x52, 0x00, 0x6F, 0x00};
但是我收到一个错误,因为0xFF和0xFE太大而无法放入一个字节(因为字节是用Java签名的)。更确切地说,错误是int无法转换为字节。我知道我可以使用强制转换显式地从int转换为byte并获得所需的结果,但这不是我的问题。
为了尝试一些东西,我创建了一个String并调用了getBytes(“UTF-16”)然后打印了数组中的每个字节。输出有点令人困惑,因为前两个字节是0xFFFFFFFE 0xFFFFFFFF,后跟0x00 0x52 0x00 0x6F。 (显然这里的字节顺序与我上面尝试创建的不同,但这并不重要。)
使用此输出我决定尝试以相同的方式创建我的字节数组:
byte[] bytes = new byte[] {0xffffffff, 0xfffffffe, 0x52, 0x00, 0x6F, 0x00};
奇怪的是,它运作良好。所以我的问题是,为什么Java允许0xFFFFFF80或更大的整数值自动转换为没有显式强制转换的字节,但是任何等于或大于0x80的东西都需要显式强制转换?
答案 0 :(得分:10)
这里要记住的关键是Java中的int
是一个带符号的值。当您分配0xffffffff
(2^32 -1
)时,会将其转换为有价值的值-1
- int
实际上不能代表0xffffffff
那么大的内容作为正数。
因此,对于小于0x80且大于0xFFFFFF80的值,生成的int
值介于-128和127之间,可以明确地表示为byte
。超出该范围的任何东西都不可能,并且需要强制使用显式强制转换,在此过程中丢失数据。
答案 1 :(得分:2)
如果使用没有提示的数字(例如1234L很长),编译器会假定一个整数。值0xffffffff
是一个值为-1
的整数,可以在没有警告的情况下强制转换为byte
。
答案 2 :(得分:0)
因为0xffffffff是数字-1而-1可以解释为一个字节。
答案 3 :(得分:0)
0xff
与撰写0x000000ff
相同,而不是0xffffffff
。这就是你的问题;整数是正数(255),但是字节(如果逐位转换)将是负数(-1)。但0xffffffff
为-1 int
和byte
。
答案 4 :(得分:0)
因为int是有符号的,0xffffffff代表-1,而0xff代表一个255的整数,它不在一个字节的-128(0x80)+127(0x7f)范围内。