【转】【java】java中的byte,以及它与int的转化

在做用udp传文件的东西,遇到了一个传数字的问题,研究了几个小时,发现java即使是传long的数,如果它的大小比较小也只是用2个byte传送的。至于byte[]和int的转化,java中是有接口的:Integer.parseInt(String),觉得有用的摘录在底下。为了一个数,熬红了眼睛……哎

 

另外呢,就是发现所有的String在传的时候,接受后显示(用System.out.println()输出)最后都会多一个空(0x00),猜想那是因为字符串后面都会有个/0导致的。不过没有证实。

 

 

源链接:http://lupengbj.blog.163.com/blog/static/1294293992010112283434553/

其他有用的链接:http://www.360doc.com/content/11/0317/10/3700464_101894110.shtml

http://hi.baidu.com/netbusy/blog/item/9684b60aa36b703cb1351dd8.html

 

 

 

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; 
 }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值