在Java中,对 byte 和 short 类型 进行位操作的时候,严重留意事项
总结:在java中,对byte和short类型的 右移操作 必须先进行 & 0xff 后再右移,避免byte或short是负数的情况下,导致 右移操作前 自动升为int,前面补了很多1,此时右移会把1冲到高位上,从而错误;
int 和 long没有任何问题;
左移没有这个问题,因为左移及时自动转换成int 在前面补了很多1后,后面的截断 还是会把左边的都截掉,就是说 左移 永远是从右边补0,而右移由于自动转换成int的存在,会导致即使使用了>>>的情况下
左边还是会补1,因为负数转换成int的时候,前面的每一位都是1了。留意。
((bytes[0] & 0xff) >>> 3);
1.举例:
public static void main(String[] args) {
byte[] bytes = new byte[1];
bytes[0] = 31;//00011111
bytes[0] <<= 3;//11111000
bytes[0] >>>= 3;// 这步很诡异的变成了 11111111 ????
System.out.println(bytes[0]);// -1;最终的结果为-1???
}
接下来调试看下:




导致输出的结果为-1,而不是31的原因是,在java中 对byte和 short进行位操作的话,会先默认自动转换为int 再进行位操作;
public static void main(String[] args) {
byte[] bytes = new byte[1];
bytes[0] = 31;//00011111
/*
bytes[0] <<= 3;这步发生的情况如下:
0000 0000 0000 0000 0000 0000 0001 1111(先把byte[0]转换成int)
0000 0000 0000 0000 0000 0000 1111 1000(再左移3位)
1111 1000(再赋值给byte[0],截断)
*/
bytes[0] <<= 3;
/*
bytes[0] >>>= 3; 又发生了什么:
1111 1111 1111 1111 1111 1111 1111 1000(把当前的byte[0]转换成int,由于是负数,所以转换成了这样,左边按符号位全部补1,就是由这步自动转换导致了问题,解决方法就是把这步自动转换前面的1去除,用 & 0xff)
0001 1111 1111 1111 1111 1111 1111 1111(右移3位)
1111 1111(赋值截断,最终 byte[0]的值,可见变成全是1了)
*/
bytes[0] >>>= 3;
/*
输出byte[0]发生了什么,输出byte[0]就是把byte[0]的值转换成10进制,计算机发现byte[0]的最高位是1,说明是负数,
计算机认为它是负数后,负数在计算机中是以补码的方式来存储的,所以具体的10进制的值是它的原码,需要把补码转换成原码
规则:1.补码符号位不变,其余位取反;
2.取反后加1,就是原码
1000 0000(符号位不变,其余位取反)
1000 0001(取反后加1,就是原码)
原码就是具体的值,可见是-1
*/
System.out.println(bytes[0]);
}
解决方法,系统自动把byte[0]由byte自动向int 转换后的值再与0xff取与运算,使其一个字节的前面的位全部为0:
1111 1000 --> 1111 1111 1111 1111 1111 1111 1111 1000(自动向int转换)
然后我们再通过& 0xff 让它们取与运算:
1111 1111 1111 1111 1111 1111 1111 1000
0000 0000 0000 0000 0000 0000 1111 1111
=
0000 0000 0000 0000 0000 0000 1111 1000(这个才是我们想要的)
与&0xff 运算后,再说右移的事,就解决了这个问题;
总结:在java中,操作byte右移前一定要先 &0xff 做与运算,才能右移;
public static void main(String[] args) {
byte[] bytes = new byte[1];
bytes[0] = 31;//00011111
bytes[0] <<= 3;
bytes[0] = (byte) ((bytes[0] & 0xff) >>> 3);
System.out.println(bytes[0]);
}

==================================================================================================================
接下来看下short:

看下 int :

看下long:

在Java中,对 byte 和 short 类型 进行位操作的时候,严重留意事项的更多相关文章
- 详解java中的byte类型
Java也提供了一个byte数据类型,并且是基本类型.java byte是做为最小的数字来处理的,因此它的值域被定义为-128~127,也就是signed byte.下面这篇文章主要给大家介绍了关于j ...
- 深入理解java中的byte类型
作者 | 进击的石头--GO! 来源 | https://www.cnblogs.com/zl181015/p/9435035.html#4432849 Java也提供了一个byte数据类型,并且是基 ...
- java中如何理解:其他类型 + string 与 自增类型转换和赋值类型转换
java中如何理解:其他类型 + string 与 自增类型转换和赋值类型转换 一.字符串与其他类型连接 public class DemoString{ public static void mai ...
- java中读取特殊文件的类型
java中读取特殊文件的类型: 第一种方法(字符拼接读取): public static String getType(String s){ String s1=s.substring(s.index ...
- java中的byte
8 bit (位) = 1 Byte (字节) java中的byte就是Byte 1024 Byte = 1KB 1024 KB = 1MB 1:“字节”是byte,“位”是bit : 2: 1 by ...
- Java中的基本类型和包装类型区别
首先看一下几个测试题,验证一下java中对基本类型和包装类型的理解,看看最后输出的答案对不对,答案在这篇博客中哦: // 第一题: 基本类型和包装类型 int a = 100; Integer b = ...
- Java中的两种异常类型及其区别?
Java中的两种异常类型是什么?他们有什么区别? Throwable包含了错误(Error)和异常(Excetion两类) Exception又包含了运行时异常(RuntimeException, 又 ...
- JAVA中如何获取变量的类型
JAVA中如何获取变量的类型? package xiya; public class Demo { public static void main(String[] args) { String ty ...
- java 彻底理解 byte char short int float long double
遇到过很多关于 数值类型范围的问题了,在这做一个总结,我们可以从多方面理解不同数值类型的所能表示的数值范围 在这里我们只谈论 java中的数值类型 首先说byte: 这段是摘自jdk中 Byte.ja ...
- (转) Java中的负数及基本类型的转型详解
(转) https://my.oschina.net/joymufeng/blog/139952 面这行代码的输出是什么? 下面两行代码的输出相同吗? 请尝试在Eclipse中运行上面的两个代码片段, ...
随机推荐
- hbulider 运行微信开发者工具 Enable IDE Service (y/N) [27D[27C
问题:hbulider 运行微信开发者工具 出现如下页面,没有输入y的交互界面 解决办法:先安装微信开发者工具,然后打开微信开发者工具 再次运行:
- 如何在编码阶段减少代码中的bug?
前言 作为一名合格的程序员,不写bug是不可能的.如何花费最少的时间来修复bug呢? 在编码阶段借助一些静态分析工具往往可以事半功倍,减少代码中的bug. 静态分析工具能够在代码未运行的情况下分析源代 ...
- 淘宝flexible.js源码分析
下面三种情况都会刷新页面,都会触发load事件. 1.a标签的超链接. 2.F5或者刷新按钮(强制刷新) 3.前进后退按钮 但是火狐中,有个特点,有个"往返缓存",这个缓存中不仅保 ...
- 简单的winform学生管理系统Demo
界面效果 练习重点 1. 关系表的创建 2. 增删改查的操作,及sqlhelper的封装 3. 跨页面数据传递,编辑页数据提交后数据局步刷新到列表数据 项目源码 FrmStuddentList pub ...
- 【荐】开源Winform控件库:花木兰控件库
微信好友推荐,挺好看的Winfrom控件库,下面来看看. 介绍 基于 C#(语言) 4.0 . VS2019 . Net Framework 4.0(不包括Net Framework 4.0 Clie ...
- 青少年CTF训练平台 — CRYPTO通关WP
A2-Crypto Caesar vxshyk{g9g9g099-hg33-4f60-90gk-ikff1f36953j} 凯撒解码 qsnctf{b9b9b099-cb33-4a60-90bf-df ...
- SpringBoot3集成Zookeeper
标签:Zookeeper3.8 ,Curator5.5: 一.简介 ZooKeeper是一个集中的服务,用于维护配置信息.命名.提供分布式同步.提供组服务.分布式应用程序以某种形式使用所有这些类型的服 ...
- Git-分支-branch-checkout-merge
- [转帖]修改Linux内核参数,减少TCP连接中的TIME-WAIT
https://www.cnblogs.com/xiaoleiel/p/8340346.html 一台服务器CPU和内存资源额定有限的情况下,如何提高服务器的性能是作为系统运维的重要工作.要提高Lin ...
- GB18030-2022 标准学习
GB18030-2022 标准学习 下载 https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=A1931A578FE14957104988029B08 ...