#前言
好久都没有写博客,最近一直我可能要疯狂的写博客了,上几周吸收了很多的知识,接触的都是0和1,睡觉都是0和1,急躁的内心,我都开始有点掉头发了
#转型
最开始的时候对于转型问题真的是没有太多的理解,只是知道向上转型和向下转型,高的如果向下装丢失数据,所以下可以向上转型,但是从来没有深刻的体会到对于计算机内容的转型,下面说一下具体实例来吧
##实例
首先说一下int类型是4个字节,short是2个字节,1个字节代表的是8位,下面我说的是关于int类型转换为short类型
short类型大小为最小值:
Short.MIN_VALUE=-32768 (-2的15此方)
最大值:Short.MAX_VALUE=32767 (2的15次方-1)
int类型大小
最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)
最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1)
最开始的时候我没有注意到转型问题,然后让int类型直接转换为short类型,但是突然间发现有问题,可以看出32769完全超出了我们的长度,所以这个时候再java里面是由正负号的(C中是没有的),所以这个时候最终的short会是负数的,但是你会发现的就是这样也没有关系,因为在java里面他直接都帮助我们处理,用负数进行代替了,所以比较方便。
下面我需要做的就是不能使用short类型,直接使用int类型,之前的short是2个byte,前在是int类型,所以会是4个字节,32位,下面的内容就是转换问题,和具体的步骤
1.把int类型转换为32位的字节
2抽取后16位字节
3把16字节转换为2字节,2个字节正好是short类型
4然后put进行
在这里要说明的就是字节和字有的时候会搞混,字节是用数组表示的,例如byte[] 里面存储的是0,1,对于字他表示的byte。一个字节8个字,也就是8位,位就是字
byte[] bytes= Utilities.intToByte32(32769);
//声明一个二进制的16字节的数组
byte[] byteshort=new byte[16];
//要知道16字节里面有32位,所以我们从16的index开始取数据存储到byteshort数组里面
System.arraycopy(bytes,16,byteshort,0,byteshort.length);
//把16字节的数组转换为2个字节,也是short类型。
this.MessageID=Utilities.byte16ToShort(byteshort);
//最后一步是放到我们的缓冲区中
byteBuf.putShort(this.MessageID);
/**
*将int转换为32位byte.
* 实际上每个8位byte只存储了一个0或1的数字
* 比较浪费.
* @param num
* @return
*/
public static byte[] intToByte32(int num) {
byte[] arr = new byte[32];
for (int i = 31; i >= 0; i--) {
// &1 也可以改为num&0x01,表示取最地位数字.
arr[i] = (byte) (num & 1);
// 右移一位.
num >>= 1;
}
return arr;
}
/**
* byte转换为short类型
*
* @param arr
* @return
*/
public static short byte16ToShort(byte[] arr) {
if (arr == null || arr.length != 16) {
throw new IllegalArgumentException("byte数组必须不为空,并且长度为16!");
}
short sum = 0;
for (int i = 0; i < 16; ++i) {
sum |= (arr[i] << (15 - i));
}
return sum;
}
##java中位运算符
可能我写了上面的代码之后你还是不太明白,下面我们得把java中的为运算符搞通,在java中我们会遇到二进制位运算,并且他们在运算的时候会自动的转换为二进制进行运算
位运算符有:
1.&与运算
2.I或匀速
3.~ 取反运算
4.>>向右移动,指的是二进制的数的index
5.<< 向左移动
6.>>> 无符号向右移动,不足补0
另外说一下,在java中我们使用的是补码进行运算,也就是源码进行反码,然后再进行补码,最后就是我们java的运行方式,所以你会在java中看见有负数,但是在C中你是看不见负数的,这就是他们之间的区别
原码:如果当前的是的十进制是-1,那么用二进制表示就是1 000 0001,最高位表示负数
反码:对于反码来说整数就是原码,但是对于负数来说,就是处符号位以外取反,所以就变成:1 111 1110
补码:就是在原有的反码基础上加1,所以结果就是1111 1111
#总结
通过这次的深入了解让我对于java的内存中运算有了不一样的理解,发现真的是又恨又爱,刚开始真的不会,天天发愁,感觉头发都在掉,不过还好,回过头看,才知道自己在那里栽坑了,在byte[]里面他可以放二进制,也可以放十进制,也可以放16进制,所以这个时候需要你转,有的时候数组越界也要检查清楚,因为是从0开始,所以你最后要减一。下一篇见解buffer。你是否对于数据包封装和解析充满好奇呢?期待下下篇把。。。