int与byte的区别
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的区别的更多相关文章
- Java教程——int与Integer的区别
首先说一下int和Integer的区别: int 是基本数据类型,Integer是int的包装类.注意:后者的类型是"类".例如使用泛型,List<Integer> n ...
- java int和Integer的区别
今天偶然和同学讨论到int和Integer的区别是,发现自己对这个问题了解的并不是很清楚,而且有些概念还是错的,所以在这对int和Integer的区别做一个总结. int与integer的区别从大的方 ...
- Java进阶(三十五)java int与integer的区别
Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...
- (转)Java进阶java int与Integer的区别
Java进阶java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象,用一个引 ...
- 聊聊面试-int和Integer的区别
最近面试了很多候选人,发现很多人都不太重视基础,甚至连工作十几年,项目经验十几页的老程序员,框架学了一大堆,但是很多 Java 相关的基础知识却很多都答不上来.还有很多人会回答,只知道要用,但是从来不 ...
- Byte和byte的区别
Byte和byte的区别 背景 今天学习网络编程中,在建立Udp连接时,使用byte[]数组接收传输的数据,但是byte[]错写为Byte[],导致错误. //接收数据: Byt ...
- int[] convert byte[]
private void button_Click(object sender, RoutedEventArgs e) { byte[] bytes = this.ConvertIntArrayToB ...
- java int与integer的区别
int与integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象 1.Java 中的数据类型分为基本数据类型 ...
- [转载]java int与integer的区别
声明: 本篇文章属于转载文章,来源:
随机推荐
- sf中schedule设定
博客园龄有两年多了,看了一下我发的文章数和最后发布的日期,不禁的心头一怔,已经有一年都没有写更新博客了.突然想起一个句子好像说的是我:间歇性踌躇满志,持续性懒惰等死.最近也看到一位好朋友的qq个性签名 ...
- 利用LinkedList实现洗牌功能
分2步: 1.生成扑克牌. 2.洗牌. package com.dongbin.collection; import java.util.LinkedList; import java.util.Ra ...
- android 简单粗暴的注解初始化View学习
原理是在Activity加载好后通过找到Activity中使用注解的字段,再通过Java反射的方式,动态的给这个字段设置值. 1定义一个注解接口 /** * view inect by id * * ...
- Maxwell顺态求解器电磁力分析
文源:技术邻 问题描述:求解一段通有正弦交流电的直导线在某一稳态磁场中的受力情况,并简单验证仿真结果. 模型介绍: 如上几何模型中10mm边长立方体代表永磁体,材料属性为材料库中的NdFe35,修改磁 ...
- Spring 整合 Redis出现的一个Timeout方法找不到的问题
直接说问题吧. 依赖包:jedis 2.9.0. spring-data-reids 1.4.1 提示:redis.clients.jedis.JedisShardInfo.setTimeout(I) ...
- Arduino使用注意问题及编程相关
1.Arduino的概念 arduino是一款便捷灵活方便上手的开源电子原型平台,包含硬件(各种型号的arduino板)和软件(arduino IDE), 是一个基于开放原始码的软硬件平台,构建于开放 ...
- 第六十二节,html分组元素
html分组元素 学习要点: 1.分组元素总汇 2.分组元素解析 本章主要探讨HTML5中分组元素的用法.所谓分组,就是用来组织相关内容的HTML5元素,清晰有效的进行归类. ...
- java--方法重写与重载
方法重写 /*方法重写(一般多用在继承上) 定义:它是指子类和父类的关系,子类重写了父类的方法. 两个方法返回值.方法名.参数列表必须完全一致! 出现原因:在Java中,子类可继承父类中的方法,而不需 ...
- SOJ 1210 二叉树
1210. 二叉树 Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description 在众多的数据结构中,二叉树是一种特殊而重要的结构,有 ...
- kettle 连接Hadoop 遇错
kettle从windows中往hdfs中写文件