无意间翻看之间的代码,发现了一段难以理解的代码。

     byte[] bs = digest.digest(origin.getBytes(Charset.forName(charsetName))) ;  

        for (int i = 0; i < bs.length; i++) {
int c = bs[i] & 0xFF ;
if(c < 16){
sb.append("0");
}
sb.append(Integer.toHexString(c)) ;
}
return sb.toString() ;

bs是由一段字符串经过MD5加密后,输出的byte数组。我起初难以理解为什么在接下来的循环中要将bs[i]&oxFF再复制给int类型呢?

bs[i]是8位二进制,0xFF转化成8位二进制就是11111111,那么bs[i]&0xFF不是还是bs[i]本身吗?有意思吗?

后来我又写了一个demo

package jvmProject;

public class Test {

    public static void main(String[] args) {
byte[] a = new byte[10];
a[0]= -127;
System.out.println(a[0]);
int c = a[0]&0xff;
System.out.println(c);
}
}

我先打印a[0],在打印a[0]&0xff后的值,本来我想结果应该都是-127.

但是结果真的是出人意料啊!

-127

129

到底是为什么呢?&0xff反而不对了。

楼主真的是不懂啊,后来往补码那个方向想了想。

记得在学计算机原理的时候,了解到计算机内的存储都是利用二进制的补码进行存储的。

复习一下,原码反码补码这三个概念

对于正数(00000001)原码来说,首位表示符号位,反码 补码都是本身

对于负数(100000001)原码来说,反码是对原码除了符号位之外作取反运算即(111111110),补码是对反码作+1运算即(111111111)

概念就这么简单。

当将-127赋值给a[0]时候,a[0]作为一个byte类型,其计算机存储的补码是10000001(8位)。

将a[0] 作为int类型向控制台输出的时候,jvm作了一个补位的处理,因为int类型是32位所以补位后的补码就是1111111111111111111111111 10000001(32位),这个32位二进制补码表示的也是-127.

发现没有,虽然byte->int计算机背后存储的二进制补码由10000001(8位)转化成了1111111111111111111111111 10000001(32位)很显然这两个补码表示的十进制数字依然是相同的。

但是我做byte->int的转化 所有时候都只是为了保持 十进制的一致性吗?

不一定吧?好比我们拿到的文件流转成byte数组,难道我们关心的是byte数组的十进制的值是多少吗?我们关心的是其背后二进制存储的补码吧

所以大家应该能猜到为什么byte类型的数字要&0xff再赋值给int类型,其本质原因就是想保持二进制补码的一致性。

当byte要转化为int的时候,高的24位必然会补1,这样,其二进制补码其实已经不一致了,&0xff可以将高的24位置为0,低8位保持原样。这样做的目的就是为了保证二进制数据的一致性。

当然拉,保证了二进制数据性的同时,如果二进制被当作byte和int来解读,其10进制的值必然是不同的,因为符号位位置已经发生了变化。

象例2中,int c = a[0]&0xff;  a[0]&0xff=1111111111111111111111111 10000001&11111111=000000000000000000000000 10000001 ,这个值算一下就是129,

所以c的输出的值就是129。有人问为什么上面的式子中a[0]不是8位而是32位,因为当系统检测到byte可能会转化成int或者说byte与int类型进行运算的时候,就会将byte的内存空间高位补1(也就是按符号位补位)扩充到32位,再参与运算。上面的0xff其实是int类型的字面量值,所以可以说byte与int进行运算。

(原文地址:http://www.cnblogs.com/think-in-java/p/5527389.html)

[转]byte为什么要与上0xFF?的更多相关文章

  1. byte为什么要与上0xff?

    无意间翻看之间的代码,发现了一段难以理解的代码. byte[] bs = digest.digest(origin.getBytes(Charset.forName(charsetName))) ; ...

  2. byte为什么要与上0xff(转)

    无意间翻看之间的代码,发现了一段难以理解的代码. byte[] bs = digest.digest(origin.getBytes(Charset.forName(charsetName))) ; ...

  3. byte & 0xff char 转换

    https://blog.csdn.net/lixingtao0520/article/details/75450883 版权声明:本文为博主原创文章,转载请注明作者与出处,http://blog.c ...

  4. byte为什么要与0xff

    面对带正负号的数,会采用符号扩展,如果原值是正数,则高位补上0:如果原值是负数,高位补1.二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.当前的计算机系统使用的基本上是二 ...

  5. java byte&0xFF

    做串口端口通讯时,数据都是以byte类型发送的 普通的byte范围是-128-127,而java的byte范围是0-255 因此将数据的byte转成java的byte时,需要与0xff(1111111 ...

  6. [转]java中byte转换int时为何与0xff进行与运算

    在剖析该问题前请看如下代码public static String bytes2HexString(byte[] b) {  String ret = "";  for (int ...

  7. Java中byte与16进制字符串的互换原理

    我们都知道Java中的byte是由8个bit组成的,而16进制即16中状态,它是由4个bit来表示的,因为24=16.所以我们可以把一个byte转换成两个用16进制字符,即把高4位和低4位转换成相应的 ...

  8. byte ---> hex String

    public static String byte2HexString(byte[] b){ String ret = ""; ;i<b.lenght;i++){ Strin ...

  9. 从JDK源码角度看Byte

    Java的Byte类主要的作用就是对基本类型byte进行封装,提供了一些处理byte类型的方法,比如byte到String类型的转换方法或String类型到byte类型的转换方法,当然也包含与其他类型 ...

随机推荐

  1. 对Bootloader(引导加载程序)的几点理解

    1.在加电复位之后,大多数处理器都会从一个默认的地址处获取代码.比如MIPS结构的CPU会从0xBFC00000处取第一条指令,而ARM结构的CPU则从地址0x00000000处取第一条指令.因此,在 ...

  2. MongoDB副本集配置系列六:定位MongoDB慢的原因

    1:想知道哪些操作拖慢了MongoDB的速度,首先需要检查当前正在执行哪些操作. gechongrepl:PRIMARY> db.currentOp() "opid" : 7 ...

  3. SSM实战——秒杀系统之Web层Restful url设计、SpringMVC整合、页面设计

    一:Spring整合SpringMVC 1:编写web.xml,配置DispatcherServlet <web-app xmlns="http://java.sun.com/xml/ ...

  4. [转]jquery设置select选中,赋值等操作

    一.基础取值问题 例如<select class="selector"></select> 1.设置value为pxx的项选中 $(".selec ...

  5. 【Fanvas技术解密】HTML5 canvas实现脏区重绘

    先说明一下,fanvas是笔者在企鹅公司开发的,即将开源的flash转canvas工具. 脏区重绘(dirty rectangle)并不是一门新鲜的技术了,这在最早2D游戏诞生的时候就已经存在. 复杂 ...

  6. 【DB2】监控动态SQL语句

    一.db2监控动态SQL(快照监控) db2示例用户登陆后,使用脚本语句db2 get snapshot for all on dbname>snap.out 也可以使用db2 get snap ...

  7. excel如何快速更改表格边框的颜色

    1.当完成基本的表格设置之后,对颜色不甚满意,怎么办 2.重新给表格选择一种颜色,这里会出现一个“笔”形状的鼠标箭头,不用理睬她 3.再次给表格统一加边框即可(开始--边框--所有框线)

  8. <c:url>标签相关知识点

    <c:url>标签: value:指定路径!他会在路径前面自动添加项目名. <c:url value="/index.jsp"/>,他会输出/day14/i ...

  9. 7216:Minecraft

    总时间限制: 1000ms内存限制: 65536kB 描述 Minecraft是一个几乎无所不能的沙盒游戏,玩家可以利用游戏内的各种资源进行创造,搭建自己的世界. 在Minecraft中,基本的建筑元 ...

  10. ISO七层协议

    1 OSI参考模型 谈到网络不能不谈OSI参考模型,虽然OSI参考模型的实际应用意义不是很大,但其的确对于理解网络协议内部的运作很有帮助,也为我们学习网络协议提供了一个很好的参考.在现实网络世界里,T ...