2009-12-20 121 views
9

我即将开始研究需要读取字节和创建字符串的内容。正在读取的字节表示UTF-16字符串。所以我只想测试一下,我想将一个UTF-16编码的简单字节数组转换为一个字符串。数组中的前2个字节必须表示字节序,因此必须是0xff 0xfe或0xfe 0xff。所以,我想创建我的字节数组如下:Java将int隐式转换为字节

byte[] bytes = new byte[] {0xff, 0xfe, 0x52, 0x00, 0x6F, 0x00}; 

但我得到了一个错误,因为0xFF和0xFE的太大而无法放入一个字节(因为字节在Java中签)。更准确地说,错误是int不能被转换为一个字节。我知道我可以通过一个强制转换从int转换为byte并实现所需的结果,但这不是我的问题所在。

只是尝试一些东西,我创建了一个字符串,并调用getBytes(“UTF-16”),然后打印数组中的每个字节。输出有点混乱,因为前两个字节是0xFFFFFFFE 0xFFFFFFFF,后面是0x00 0x52 0x00 0x6F。 (可以想象,这里的排列顺序与我上面试图创建的不同,但并不重要)。

使用这个输出,我决定尝试和创建我的字节数组以同样的方式:

byte[] bytes = new byte[] {0xffffffff, 0xfffffffe, 0x52, 0x00, 0x6F, 0x00}; 

而且奇怪的是它工作得很好。所以我的问题是,为什么Java允许一个0xFFFFFF80或更大的整数值自动转换为一个字节而没有显式转换,但是任何等于或大于0x80的值都需要显式转换?

回答

10

这里要记住的关键是在Java中的int是一个有符号的值。当您分配0xffffffff(即2^32 -1)时,会将其转换为值为-1的带符号int - int实际上不能代表像0xffffffff那样大的值作为正数。

因此,对于小于0x80且大于0xFFFFFF80的值,得到的int值介于-128和127之间,其可以明确地表示为byte。超出这个范围的任何东西都是不可能的,并且需要强制进行明确的演员制作,并在流程中丢失数据。

+0

谢谢,这使得它更清晰。 – DaveJohnston 2009-12-20 12:41:55

2

如果您在没有提示的情况下使用数字(例如1234L很长),编译器会假定一个整数。值0xffffffff是一个整数,其值为-1,可将其转换为byte而不发出警告。

+1

...因为Java对负值使用二进制补码表示法。 – Ash 2009-12-20 12:34:52

0

因为0xffffffff是数字-1,-1可以解释为一个字节。

0

0xff与写作0x000000ff相同,而不是0xffffffff。所以这是你的问题;该整数是一个正数(255),但该字节(如果按比特转换)将是一个负数(-1)。但是0xffffffff为-1既作为int又作为byte

0

因为int是有符号的,0xffffffff代表-1,而0xff代表一个值为255的整数,它不在-128(0x80)+127(0x7f)范围内。