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位长的。。。恩。。。你明白我的意思。你想对它们进行相加运算。在这个时候你的作用就很明显了,当你对虚拟机说把它们俩给我相加成一个整数(int),那么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虚拟机会明白你的意思。
分享到:
相关推荐
主要介绍了Java中byte[]、String、Hex字符串等转换的方法,代码很简单,需要的朋友可以参考下
byte转化为int有两种情况: ... 2)保持低字节中各个位不变,3个高字节所实用0填充 应用场景:编解码操作, 方法:?用位操作:int i = aByte & 0xff。 比如:若aByte=0xff,转化为int后。i为0x000000ff。
主要整理了Java中byte数组与其他基本类型的转换
下面小编就为大家带来一篇基于java中byte数组与int类型的转换(两种方法)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
JAVA转byte[]为int,long,double
分别给大家介绍了Java中byte和int之间的转换、Java中 byte数组和int之间的转换、Java中byte数组和long之间的转换以及整理了整体工具类的源码,需要的朋友可以参考借鉴,下面来一起看看吧。
java_byte与char、String互转.................
使用链式编程写法实现Java中byte数组的拼接。例如byte[] bytes = ByteUtils.get().add(0x41).add(07).add(11).add("15288930000").add(0x45).toArray();更灵活用法请参考Mybytes
用于java,byte与各种对象的转换,Integer、short、hex、string
今天小编就为大家分享一篇关于Java中byte输出write到文件的实现方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
java基本类型与byte数组互相转换.pdf
Java bytes数组与基本类型的相互转换 Int -> Bytes int64ToByte8 int48ToByte6 int40ToByte5 int32ToByte4 int24ToByte3 int16ToByte2 int8ToByte Bytes -> Int bytesToInt64 bytesToInt48 bytesToInt40 bytesTo...
今天小编就为大家分享一篇java中两个byte数组实现合并的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
java基本类型转byte,设计原码、补码、反码、左右位移等知识,赚点积分
Java String与Byte类型转换;用到网络编程.
NULL 博文链接:https://yuhuiblog695685688425687986842568269.iteye.com/blog/2433333
做Java课程设计有用到的例子,是个看了就能上手的例子。
Java也提供了一个byte数据类型,并且是基本类型。java byte是做为最小的数字来处理的,因此它的值域被定义为-128~127,也就是...下面这篇文章主要给大家介绍了关于java中byte类型的相关资料,需要的朋友可以参考下。
Java对byte 的 + – * / >> >>> << & | ^ (加,减,乘,除,右移,左移,无符号右移,位与,位或,位异或)操作,均会是首先将byte转化为int, 再行运算。这一事实可能导致多种问题: 假设我们想进行如下...
重点讲述Java语言中容易混淆的char与byte的联系与区别