转自:https://blog.csdn.net/wojiuai2093/article/details/50779879

int i = 0;
  i += ((b[0] & 0xff) << 24);
  i += ((b[1] & 0xff) << 16);
  i += ((b[2] & 0xff) << 8);
  i += ((b[3] & 0xff));

想必大家对这样的代码并不陌生,明白就可以不看了,想了解的继续往下看,不好的地方还请多多包涵!
个人经常看到这样的写法但是不明白为何,所以忽然想了解下于是研究了下.

有一定的计算机2进制计算基础的就可以看明白,如果不明白2进制,先去看看计算机2进制计算及转换之类的东西

===========开始...

原码,反码,补码概念
+1原 = 0000 0001
-1原  = 1000 0001
反码
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
补码
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

一部分int转byte
java采用[补码]存储整数 int型为4字节 32位,byte为1字节8位
所以byte[]数组中存储一个int类型肯定是4个1字节的byte组成,即byte[4]才可以存放一个int值
就算int 是0在计算中也是占用个32位表示:00000000 00000000 00000000 00000000 存入byte中即4个下标中均为0
int直接存入byte数组中及原理:

int a =1246;
二进制表示
|------高16位----------|  |---------低16位-------|
00000000 00000000 00000100 11011110
|   A         | |   B        | |   C         | |   D         |
[0]              [1]             [2]              [3]   放入byte[]数组原理,将这个2进制以8位为1个字节存入byte数组中从数组下标0开始存入
最后byte[]数组存储为这样
[0]=00000000   补码后00000000转10进制真实数值0
[1]=00000000   补码后00000000转10进制真实数值0
[2]=00000100   补码后00000100转10进制真实数值4
[3]=11011110   补码后10100010转10进制真实数值-34,
                         最后8位11011110最高位是符合位,1负0正,补码规则: 符号位不变, 其余各位取反, 
                         最后+1得到:10100010 0100010=34+负号"1"所以=-34
转换过程中进行&运算就是高位舍去,通俗就是不需要的数据清0处理,下面琢行说明:

由于byte只有8位,int32位,所以我们需要位移,把前面的每8位一组移动到最后8位上面来进行计算,其他数值都不参与计算
int a =1246;
byte[] b = new byte[4];
第一步:
b[0] = (byte) (a >> 24 & 0xff);
将00000000 00000000 00000100 11011110 A区域移动到D区域往右边推动24位,主要获取A取的值
00000000 00000000 00000100 11011110
                                                   00000000 00000000 00000100 11011110形成这样的
空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
00000000 00000000 00000000 00000000
最后做&计算,这里移动了24位,右边的数据都被溢出了,做不做这个计算都没影响,还是表示下
00000000 00000000 00000000 00000000
00000000 00000000 00000000 11111111  &计算0xFF的2进制
-------------------------------------------------------
 00000000 00000000 00000000 00000000 结果还是0

第二步:
b[1] = (byte) ((a >> 16) & 0xff);
将00000000 00000000 00000100 11011110 B区域移动到D区域往右边推动16位,主要获取B取的值
00000000 00000000 00000100 11011110
                                  00000000 00000000 00000100 11011110形成这样的
空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
00000000 00000000 00000000 00000000
00000000 00000000 00000000 11111111  &计算0xFF的2进制
---------------------------------------------------------
00000000 00000000 00000000 00000000 结果还是0

第三步:
b[2] = (byte) ((a >> 8) & 0xff);
将00000000 00000000 00000100 11011110 C区域移动到D区域往右边推动8位,主要获取C取的值
00000000 00000000 00000100 11011110
                 00000000 00000000 00000100 11011110形成这样的
空白的数据被抹掉就是0表示,移动后超出了D区域数据属于溢出情况也舍掉最后形成如下
00000000 00000000 00000000 00000100
00000000 00000000 00000000 11111111  &计算0xFF的2进制
-------------------------------------------------------
00000000 00000000 00000000 00000100补码后的2进制,上面的每一步最后都要参与补码,只是因为0就没写了
 转10进制最终结果是4

第四步:
b[3] = (byte) (a & 0xff);
将00000000 00000000 00000100 11011110 计算D区的值,由于D取直接就是在末尾8位上,所以不需要移动,
直接&计算,这里充分体现出来&0xFF计算就是清除其余不需要的数据,由于8位前还有0100 这么个数,
但是我们只需要后8位,所以&FF计算清除掉
00000000 00000000 00000100 11011110
00000000 00000000 00000000 11111111  &计算0xFF的2进制
-------------------------------------------------------
00000000 00000000 00000000 11011110结果
这个结果转10进制:222,可见是有问题的,int->byte我们只需要拿出最后8位出来进行处理11011110,
上面提过最高位(左边0的位置)是符号位:0表示正数,1表示负数
计算过程中只看后面7位1011110转10进制:94加上前面的符号得到-94,但这个数也不对
因为java采用补码存储整数
所以我们需要对1011110这个负数进行补码:负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
1011110
1100001再+1 1100001+1=1100010
最后1100010转10进制(只看后面7位100010):34前面加符号-34才是最终结果

二部分byte转int
对于一个单一的byte转int就是其本身,因为byte范围是-128--127如果输入超过这个数直接编译不通过
byte i=12;
int c=(int)i;
c=12;

像前面一部分,int转byte后得到的是一个4字节的byte[]数组,因为int长度就是4字节,不管值有多大或是0 byte[]也是4个长度,里面的值都是0;
继续上面的最终byte[]数组中的结果是
byte[] b ={0,0,4,-34};从下标0-4存的是int类型的高位到低位的顺序
|------高16位-----------| |---------低16位--------|
00000000 00000000 00000100 11011110
|   0         | |   0         | |   4         | |  -34        |
int 到byte是向右移动,那转换回来就是反其道而行之

第一步:
00000000 00000000 00000100 11011110原2进制
                                                   00000000 00000000 00000100 11011110原来下标0的数被移右动24位
所以获取下标[0]<<24左移24位
下标[0]=0转2进制
00000000 00000000 00000000 00000000  左移24位后的2进制,因为0怎么移动都是0
00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
00000000 00000000 00000000 00000000  补码
-----------------------------------------
结果0

第二步:
00000000 00000000 00000100 11011110原2进制
                                  00000000 00000000 00000100 11011110原来下标1的数被移右动16位
所以获取下标[1]<<16左移16位,当然后面的2组数以不存在,移动后整个32位的2进制就是如下
下标[1]=0转2进制00000000
00000000 00000000 00000000 00000000  左移16位后的2进制,因为0怎么移动都是0
00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
00000000 00000000 00000000 00000000  补码
-----------------------------------------
结果0

第三部分:
00000000 00000000 00000100 11011110原2进制
                 00000000 00000000 00000100 11011110原来下标2的数被移右动8位
所以获取下标[2]<<8左移8位,当然后面的1组数以不存在,移动后整个32位的2进制就是如下
下标[2]=4转2进制00000100
 00000000 00000000 00000100 00000000  左移8位后的2进制
&00000000 00000000 00000000 11111111  再进行&FF运算,为何要&FF后面比较直观,这里是0所以不讲解了
-----------------------------------------
 00000000 00000000 00000100 00000000
 00000000 00000000 00000100 00000000补码,正数补码是其本身
 结果100 00000000转10进制=1024

第四部分:
下标[3]=-34转2进制11111111 11111111 11111111 11011110
11111111 11111111 11111111 11011110原来下标3的数就是末尾8位没有发生过移动,所以不需要位移
00000000 00000000 00000000 11111111这里比较直观&FF计算去掉不需要的数据,可以称作清0操作
-----------------------------------------
00000000 00000000 00000000 11011110结果
00000000 00000000 00000000 11011110补码后
这时11011110并不是负数,因为现在是byte转int上面进行&FF运算后最高位是0,所以是正数,正数补码就是本身
-----------------------------------------
所以转10进制后=222
将最终的4个结果相加0+0+1024+222=1246

java byte转int 互相转换原理详解相关推荐

  1. java里的进制转换函数_基于Java中进制的转换函数详解

    十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer.toOctalString(int i) 十进制转成二进制 Integer.toBinar ...

  2. Java进制转换原理详解

    在使用Java进行网络编程时,常常需要进行进制转换,而在进行这类操作时,往往需要对进制与Java数据类型有较深入的理解,才能确保在编程时不会出现错误.同时,深入了解进制能写出更加高效的代码. 本文先从 ...

  3. JAVA消息服务JMS规范及原理详解

    一.简介 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进 ...

  4. JAVA Stream的collect用法与原理(详解)

    初识Collector 先看一个简单的场景: 现有集团内所有人员列表,需要从中筛选出上海子公司的全部人员 假定人员信息数据如下: 姓名 子公司 部门 年龄 工资 大壮 上海公司 研发一部 28 300 ...

  5. 【你好面试官】008 Java内存模型指volatile底层原理详解、多处理器原子操作实现原理

    微信公众号:你好面试官 这里没有碎片化的知识,只有完整的知识体系. 专注于系统全面的知识点讲解,面试题目解析; 如果你觉得文章对你有帮助,欢迎关注.分享.赞赏. ###前言 二蛋几天没有收到面试通知, ...

  6. Java的加载与执行原理详解 Java程序从编写到最终运行经历了哪些过程

    前言 Java程序从编写到最终运行大概可概括为3个阶段:编写.编译.运行阶段. 一.编写阶段 程序员在硬盘某个位置新建一个xxx.java文件 使用记事本或者其他文本编辑器例如EditPlus打开xx ...

  7. java面试题:voliate底层原理——详解

    1. voliate底层原理 1.1 voliate变量的特点 可见性: 当一个线程修改了声明为volatile变量的值,新值对于其他要读该变量的线程来说是立即可见的. 有序性: volatile变量 ...

  8. Java byte转换为int

    Java byte到Int的转换 Java byte到Int的转换有两种: 带符号转换,数值转换 无符号转换 byte本身是带正负符号的, 默认向上转换也是带符号 带符号转换 byte本身是带正负符号 ...

  9. WEB后台--邮件和短信业务实现(包括Java一键实现、封装和异步)以及原理详解

    本来就打算针对一些固定的特别点的业务(QQ与网易邮件.拦截设计.短信.定时器等等)来进行记录以及解析原理,这些会比较零散记录在JavaWeb的分类里面,感兴趣的童鞋可以去看下. 有人问为什么要邮件短信 ...

最新文章

  1. python中分支结构有几种各有什么特点_「武鹏有课」Python分支结构的种类
  2. 谷歌:CNN击败Transformer,有望成为预训练界新霸主!LeCun却沉默了...
  3. webStrom破解链接
  4. 关于MongoDB时区问题
  5. 美国河流出现神奇冰盘 顺着水流不断旋转
  6. php中的数据库操作和字符串操作session与cookie操作,PHP的cookie与session原理及用法详解...
  7. 阿里云 MSE 微服务治理发布企业版
  8. 耗费两小时整理电子入行学习资源
  9. 分站php源码,企业网站管理系统云优CMS v2.0.5 分站版
  10. 运用getParameterNames()方法和getParameterValues()方法获取请求参数名称和内容
  11. 如何利用SPSS软件进行数据的描述性分析
  12. Android 10.0设置默认sim1卡使用数据流量和发送短信
  13. word 空格变删除 问题及解决
  14. 在Windows下批量修改文件后缀(ren命令-rename)
  15. 统计每天的新老用户,日活,周活,月活
  16. 知识总结--性能优化总结(摘录+转载)
  17. Wind数据个性化定制抓取
  18. 保研面试中常见的英语问题有哪些?
  19. 【头部姿态】头部姿态检测(一)
  20. 脉脉林凡:职场社交突破点在于行业间的融合

热门文章

  1. 浅谈跟美女上床和次贷危机
  2. 大一python期末必考题_Python期末复习材料
  3. 爬取热榜2k图片,爬虫入门即可
  4. 求一个防关联浏览器的插件,防关联浏览器破解版
  5. 双目摄像头(CSI-IMX219)的标定
  6. 文献资源下载网址经验总结
  7. 语音信号处理 (speech signal processing) - 参考文献
  8. 推荐一款可以工作汇报远程办公的电脑监控软件
  9. API电商 ERP 数据管理
  10. 李航《统计学习方法》课件