接下来的结论只是真正事实的必要条件,我不能保证充分.我会持续验证各个结论.
1.byte转int截取的是低八位
public class Test{
public static void mian(String[] args){
int i = -1;
byte[] bytes = new byte[4];
bytes[0] = (byte)((i>>0*8)*0xff);
bytes[1] = (byte)((i>>1*8)*0xff);
bytes[2] = (byte)((i>>2*8)*0xff);
bytes[3] = (byte)((i>>3*8)*0xff);
for(byte b:bytes){
Sytem.out.print(b +", ");
}
}
}//输出结果: -1, -1, -1, -1,
我们进行详细分析:
①:先计算 -1在计算机中的补码
...首先,因为 int 类型是4的字节.想表示负数,高位一定是1.对于负数,实际储存的是补码.对 负数的绝对值 取反 再加上1,即为 此负数的补码.
...实际情况下,在任意一个类型中.只要计算机判定其最高位(int 类型就是从右向左的第32位,byte类型就是从左到右第8位)是1,则会自动进行 减1取反拿到绝对值,在屏幕上输出负号接上绝对值.或者说,计算机从来不认识负值,它只有表示负值的办法而已.
....这样,得到 int类型的-1在系统的实际存储情况如下:
....1111 1111 1111 1111 1111 1111 1111 1111
②:用bytes[3]来详细讲明情况
...右移三位(就是三个字节)
...0000 0000 0000 0000 0000 0000 1111 1111
...将此类型赋值给了bytes[3],(可以看成一个byte类型的变量)
...由于byte类型只有一个字节(可以看出截取的是低八位)
...bytes[3] = 1111 1111
...注意,此时最高位已经为1了
输入结果,经过 -1 ,取反,计算.得到结果为绝对值是1,加上负号,所以屏幕打印 -1
2.Java中的Integer.toBinaryString( x)方法是将x强制转换成int类型,再以二进制在控制台输出,其他方法类似.
3.String中的getBytes(),是从指定字符串用操作系统默认的解码格式获取字节流.当然,括号内可以指定解码方式.
...已知: utf-8下:科这个字二进制编码:
...1110 0111 1010 0111 1001 0001
public class Test{
public static void main( String[] args){
String s = "科";//""是指字符串,''指的是char.注意
byte[] bytes = s.getBytes();//我的系统默认解码是utf-8
for( byte b :bytes{
System.out.println(Integer.toBinaryString(b));
}
}
}
//输出结果:
// 1111 1111 1111 1111 1111 1111 **1110 0111**
// 1111 1111 1111 1111 1111 1111 **1010 0111**
// 1111 1111 1111 1111 1111 1111 **1001 0001**
...可以看出,最后一个字节正是真正的byte的实际内容,三个字节编
...码一个字符
...还有一个有趣的内容:可以看到,低八位是真正的字节,但是
...其余三位填充的不是0,而是1.不知道为什么,应该和
...字符串脱不开关系