Java中涉及byte、short和char类型的运算操作首先会把这些值转换为int类型,然后对int类型值进行运算,最后得到int类型的结果。因此,如果把两个byte类型值相加,最后会得到一个int类型的结果。如果需要得到byte类型结果,必须将这个int类型的结果显式转换为byte类型。例如,下面的代码会导致编译失败:
class BadArithmetic
{
static byte addOneAndOne()
{
byte a = 1;
byte b = 1;
byte c = (a + b);
return c;
}
}

当遇到上述代码时,javac会给出如下提示:
type.java:6: possible loss of precision
found : int
required: byte
byte c = (a + b);
error

为了对这种情况进行补救,必须把a + b所获得的int类型结果显式转换为byte类型。

最近因为在做金融项目,里面对byte的操作要求比较多,所以在这里整理了一下关于java中的byte类型。
Java虚拟机中没有byte类型,恩。。。怎么说呢,个人感觉这个说法有点儿唬人的意思。的确,当这个想法刚刚出现在我的脑海中的时候我觉得也有些胡扯,毕竟byte类型就在那里,怎么能说Java虚拟机中没有byte类型呢?
好吧,我来稍稍的解释一下。Java虚拟机对基本类型的操作基本都是在栈上完成的(这个是可信的,因为不是我说的)。我们知道,Java在处理一个语句的时候,首先它会先把用到的操作数压到栈中,然后再从栈中弹出进行计算,最后将结果再压回到栈中。任何对byte的操作也会如此。因此,Java对byte类型操作之前会将其压入到栈中。实际上,Java压入栈的不是byte类型,而是一个标准的int类型(32位,byte是8位),也就是说,Java虚拟机将我们短小可爱的byte类型压入栈之前,会先把它拉长成int类型再压栈。不过事实上在压栈之前也是int类型.这样一来,我们不管是在栈里还是从栈里弹出的byte类型实际上都是用int的长度存储的。这也就是我为什么说,Java虚拟机中没有byte类型。因为它们都被变成了int。
int?还是byte?这么说来在Java虚拟机中处理来处理去的都是32位长的int,那么byte怎么办?换句话说,如果我们看到一个32位的int,那我们应该管它叫int呢还是叫byte呢?对于这个问题,我个人的答案是你叫丫虾米丫就是虾米。举个例子来说吧:现在栈顶端有两只。。。恩。。。32位长的。。。恩。。。你明白我的意思。你想对它们进行相加运算。在这个时候你的作用就很明显了,当你对虚拟机说把它们俩给我相加成一个整数,那么Java虚拟机会弹出这两个东西,然后相加,将结果以int类型压回到栈中。但是如果你对虚拟机说:把这两个byte相加成一个byte或者把它们俩相加成一个byte,那么Java虚拟机还是会弹出这两个东西相加,只不过前面那句会先将它们俩转换成byte再变成int,然后相加;而后面那句会直接相加。两句的最后结果都是将相加的和先转换成byte然后在变成int压入栈中。
那么,类型转换呢?这个总该是一个byte了吧!
可惜,我只能说类型转换的过程中会出现真正的byte,但是它活不到最后就被拉长了。举个例子吧,看看下面我从有意义的程序中找出的两句毫无意义的代码吧:
int a = 1;
byte b = (byte)a;
好吧,我承认会这么写的代码,程序也不会有意义到哪儿去。但是我们就事论事。当我刚开始看到这个的时候,我非常兴奋的认为上面的那个变量b总应该是byte了吧。如果你和我一样,那么恭喜你离天才又进了一步。我只能说答案是否定的。不是为了打击你,而确确实实是否定的。是的,第二句在执行的时候确实产生了一个byte,但是很不幸,它没能活到最后。最终它被拉长成了int压入了栈中,用来做为byte变量b的值。虽然它被拉长成了32位的int,但是毕竟它是byte来的,所以身上还是有byte的血统的。怎么说呢,那就是它是被虚拟机带着符号扩展出来的。这个很好理解,byte本身就是8位0或者1的组合,你就是把8位上每一位0或者1拉的再长,充其量也就是长的长一些的0或者1的byte。所以要想变成32位,你得给byte填补24位进去。那么这24位从哪里来呢?Java虚拟机的做法就是从byte的符号位(也就是最高位)来。这就是所谓的带符号扩展。就拿上面的程序举例子吧,将1压缩成byte用二进制来看是00000001,这个我想大家都不陌生。接下来就是扩展,我们byte的符号位是正,也就是0,那么Java虚拟机就会用0来填充剩下的24位,结果就是00000000000000000000000000000001。自己数一下看我是不是漏掉了。

大家可能觉得我举的例子有些太简单了,好吧,我来说一个难的。让byte变量b等于-1。当然,不是简简单单的从-1的int类型变成-1的byte类型,而是找一个正整数的int类型,让Java虚拟机截短成-1的byte类型。那么这个正整数是几呢?说实话,我拿高级计算器试了一天,最后从google上找到了它:2147483647。只要把上面语句中a的值改成这个,byte变量b的值就会是-1。非常简单,我觉得不需要解释。对不起,我有点儿得瑟和臭屁了。我还是解释一下吧:那个2147483647整数的二进制是这样的:01111111111111111111111111111111,仔细数,是32位。现在我们要把它强制转换成byte,只有8位,所以Java虚拟机不假思索的给咱们砍掉24位,剩下8位都是1:11111111,这个当然就是那个-1了。什么?你说不是?是-127?不不不不,不要忘了,Java虚拟机中使用补码来表示的,你看到的是补码。这次再算算,-1了吧。好了,接下来就是扩充回int类型了。简单的把符号位复制24个出来就好了,结果就是11111111111111111111111111111111。这个是几?自己算吧。
总结,好了,说了这么多,我们也看到了,虽然Java虚拟机中的操作数可以是一个byte,但是不管是运算也好还是类型转换也好,最终的结果都是int。至于在执行过程中如何区别,那就全靠写程序的人自己了。如果你自己都模棱两可的话,不要指望Java虚拟机会明白你的意思。

public class Test {
public static void main(String[] args) {
int a=35461;
System.out.println(Test.byte2int(Test.int2byte(a)));
}

/**
* 将int转化成byte[]
*
* @param res 要转化的整数
* @return 对应的byte[]
*/
public static byte[] int2byte(int res) {
byte[] targets = new byte[4];
targets[0] = (byte) (res & 0xff);// 最低位
targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
targets[2] = (byte) ((res >> 16) & 0xff);// 次高位
targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。
return targets;
}

/**
* 将byte[]转化成int
* @param res 要转化的byte[]
* @return 对应的整数
*/
public static int byte2int(byte[] res) {
int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00) | ((res[2] << 24) >>> 8) | (res[3] << 24);
return targets;
}

}

int与byte的区别的更多相关文章

  1. Java教程——int与Integer的区别

    首先说一下int和Integer的区别: int 是基本数据类型,Integer是int的包装类.注意:后者的类型是"类".例如使用泛型,List<Integer> n ...

  2. java int和Integer的区别

    今天偶然和同学讨论到int和Integer的区别是,发现自己对这个问题了解的并不是很清楚,而且有些概念还是错的,所以在这对int和Integer的区别做一个总结. int与integer的区别从大的方 ...

  3. Java进阶(三十五)java int与integer的区别

    Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...

  4. (转)Java进阶java int与Integer的区别

    Java进阶java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象,用一个引 ...

  5. 聊聊面试-int和Integer的区别

    最近面试了很多候选人,发现很多人都不太重视基础,甚至连工作十几年,项目经验十几页的老程序员,框架学了一大堆,但是很多 Java 相关的基础知识却很多都答不上来.还有很多人会回答,只知道要用,但是从来不 ...

  6. Byte和byte的区别

    Byte和byte的区别 背景 今天学习网络编程中,在建立Udp连接时,使用byte[]数组接收传输的数据,但是byte[]错写为Byte[],导致错误.    //接收数据:         Byt ...

  7. int[] convert byte[]

    private void button_Click(object sender, RoutedEventArgs e) { byte[] bytes = this.ConvertIntArrayToB ...

  8. java int与integer的区别

    int与integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象 1.Java 中的数据类型分为基本数据类型 ...

  9. [转载]java int与integer的区别

    声明: 本篇文章属于转载文章,来源:

随机推荐

  1. hadoop集群免密码登陆

    今天用openstack的dashboard创建了5个instance,现在的工作就是让它们可以相互访问. 1个namenode,4个datanode. 总体思路:有namenode产生公钥和密钥,传 ...

  2. 修改虚拟机内容导致oracle不能启动

    虚拟机内存目前设置为4G,想要改变成2G,数据库启动时导致报targetmomory错误,解决办法如下: 1.查看分配的memory_target和memory_max_target大小 SQL> ...

  3. iOS身份证号码识别

    一.前言   身份证识别,又称OCR技术.OCR技术是光学字符识别的缩写,是通过扫描等光学输入方式将各种票据.报刊.书籍.文稿及其它印刷品的文字转化为图像信息,再利用文字识别技术将图像信息转化为可以使 ...

  4. win10下安装Django

    Django的核心(1.4+)可以运行在从2.5到2.7之间的任何Python版本. 我的电脑是操作系统是window10 ,内存是4G. 1.下载django 官网地址:https://www.dj ...

  5. js-字符串函数

    js字符串函数 JS自带函数concat将两个或多个字符的文本组合起来,返回一个新的字符串.var a = "hello";var b = ",world";v ...

  6. sublime text2教程

    代码编辑器或者文本编辑器,对于程序员来说,就像剑与战士一样,谁都想拥有一把可以随心驾驭且锋利无比的宝剑,而每一位程序员,同样会去追求最适合自己的强大.灵活的编辑器,相信你和我一样,都不会例外. 我用过 ...

  7. js禁止浏览器后退,防止重复支付

    <script language="JavaScript"> javascript:window.history.forward(1);</script>

  8. 1.Date对象

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 线索thread二叉树

    对于一个普通的二叉树 我们可以很明显的看到,在一个二叉树中,会有许多的空结点,而这些空结点必然会造成空间的浪费,为了解决这个问题,我们可以引入线索二叉树,把这些空结点利用起来,利用 '^' 记录给定结 ...

  10. 从零开始学Axure原型设计(入门篇)

    如果说Sketch是最美.最简洁的设计软件,那么Axure就是最强大的原型制作软件.Axure不仅能制作静态的视觉稿.页面,还能添加交互动作,是进行原型设计的最佳软件之一.虽然Axure的学习曲线比较 ...