Integer.valueOf(int i)与自动拆箱与装箱
来源:互联网 发布:淘宝怎么赚钱兼职工作 编辑:程序博客网 时间:2024/05/07 22:35
查了一下Api,valueOf(int i),返回的是i值的Integer对象,Integer.valueOf()基于减少对象的创建次数和节省内存的考虑,[-128,127]之间的数字会被缓存,当valueOf()方法传入的参数在这个范围之内,将直接返回缓存中的对象。
我们来看一下一个例子
public static void main(String[] args) { Integer a=Integer.valueOf(1); Integer b=Integer.valueOf(1); int c=1; Integer d=1; long e=1L; Integer f=Integer.valueOf(321); Integer g=Integer.valueOf(321); Long i=2L; System.out.println(a==b); //1 System.out.println(a==c); //2 System.out.println(a==d); //3 System.out.println(a==e); //4 System.out.println(c==e); //5 System.out.println(f==g); //6 System.out.println(i==(a+b)); //7 System.out.println(i.equals(a+b)); //8 }
结果为:
true
true
true
true
true
false
true
false
我们来看1,a,b都是Integer的对象,由于Integer.valueOf()缓存[-128,127]之间的数,因为传入的参数一样,所以返回的对象是一样的。与//6,即可以得到结果
对于2,因为c是数值,进行的是数值比较,a会自动拆箱,进行比较,故结果是正确的
对于3,Integer d=1和Integer d=Integer.valueOf(1)的效果是一样的,所以返回了同一个对象
对于4,e为数值,故为数值比较,a先自动拆箱为int数值,再转化为long型与e进行比较
对于5,则为c转化为long型,与e进行比较
对于7,因为a+b是算术运算,故a+b是一个值,“==”运算在遇到算术运算时会自动拆箱,成为int型的值,再转型成long型,与i的自动拆箱进行比较
对于8,因为Long型的equals()方法不处理数据转型的关系,故比较是错误的。
下面的内容摘自《effective java》第49条:基本类型优先于装箱基本类型
我们知道Java有一个类型系统由两个部分组成,包括基本类型,例如int,double和boolean,和引用类型,如String和List,每个基本类型对应于一个引用类型,称作装箱基本类型。即装箱基本类型中对应于int,double和boolean的是Integer,Double和Boolean。
下面我们来看一个很有趣的例子:
public static void main(String[] args) { // TODO Auto-generated method stub Integer a=new Integer(1); Integer b=new Integer(1); System.out.println(a<b?-1:(a==b?0:1)); }
在上面的例子中,如果我们不注意的话,我们得到的结果就是0,但是运行之后我们得到的结果是1;
根据《effective java》书上的解释,首先先比较a < b,执行这个计算会使得a,b进行自动拆箱,变成基本类型(此时基本类型就只有值),第一个比较不正确,则进行第二个比较,对于“==”的比较,则比较他的同一性,即这是装箱基本类型(引用类型)的比较,即比较它们的同一性,如果a和b引用表示同一个int值的不同Integer实例,则这个比较操作返回的值是false,故上面的程序返回的是1。
对于基本类型和装箱基本类型的区别有三点:
一、基本只有值,而装箱基本类型具有与它们的值不同的同一性,换句话说,就是两个装箱基本类型可以具有相同的值而有不同的同一性。(还是很生涩,照我的理解是,虽然它们的值相同,但是a和b是两个不相同的对象,它们在创建时地址是不一样的)
二:基本类型只有功能完备的值,而每个装箱基本类型除了它有对应的基本类型的所有功能之外,还有个非功能值:null
三:基本类型通常比装箱基本类型更节省时间和空间
现在我们来看看反编译的结果
import java.io.PrintStream;public class Autoboxing{ public Autoboxing() { } public static void main(String args[]) { Integer a = new Integer(1); Integer b = new Integer(1); System.out.println(a.intValue() >= b.intValue() ? ((int) (a != b ? 1 : 0)) : -1); }}
从上面的结果可以看出,在编译时,系统先给类添加了一个无参构造器,我们着重看下输出的比较部分,
首先先对对象a和b进行同一性的比较,比较的结果为true,故结果返回1,再对a>=b进行比较,首先先对a和b进行自动拆箱,用到intValue()方法进行拆箱,此时a和b都是基本类型,故单纯比较它们值是相等的,比较的结果为true,故结果返回1。所以整个程序的返回的结果是1。
下面我们再来看看例子:
public static void main(String[] args) { Integer a=1; Integer b=1; Integer c=Integer.valueOf(1); Integer d=2; Long e=2L; System.out.println(a==b); System.out.println(a==c); System.out.println(b==c); System.out.println(d==(a+b)); System.out.println(d.equals(a+b)); System.out.println(e.equals(d)); }
上面程序的结果为:
true
true
true
true
true
false
下面我们用反编译的程序解释上面的结果
public class Autoboxing2{ public Autoboxing2() { } public static void main(String args[]) { Integer a = Integer.valueOf(1); Integer b = Integer.valueOf(1); Integer c = Integer.valueOf(1); Integer d = Integer.valueOf(2); Long e = Long.valueOf(2L); System.out.println(a == b); System.out.println(a == c); System.out.println(b == c); System.out.println(d.intValue() == a.intValue() + b.intValue()); System.out.println(d.equals(Integer.valueOf(a.intValue() + b.intValue()))); System.out.println(e.equals(d)); }}
首先对a,b进行自动装箱,用到valueOf()方法,这个方法在上面已经介绍过,故我们知道a,b和c具有同一性,故前三个比较返回的是true。
对于第四个比较,a+b,则先对a和b用intValue()方法进行自动拆箱,相加得到2这个值,再用对象d和值2进行”==”比较,对象d再用intValue()方法进行自动拆箱,得到2这个值,故结果返回的是true。
第五个比较则是先对a和b用intValue()方法进行自动拆箱,相加得到2这个值,再进行自动装箱,变成与对象d具有同一性,故返回的是true。
第六个比较,两个对象为不同的对象,故用equals方法比较返回的是false。
总结:
1、反编译的代码用了Integer.intValue()和Integer.valueOf()方法进行自动拆箱和自动装箱
2、在范围[-128,127]内的数值,自动装箱方法Integer.valueOf()会缓存,当valueOf()方法传入的参数在这个范围之内,将直接返回缓存中的对象,基于减少创建对象的次数和节省内存的考虑
3、通过”==”比较两个自动装箱的Integer实例时,只要两者表示的数值相等,结果就是相等的,因此他们的同一性是相同的
4、通过equals来比较的时候,只要同类型(包括自动装箱和拆箱)代表的数值相同的,就是相等的
- Integer.valueOf(int i)与自动拆箱与装箱
- 巧记Integer int 自动装箱与拆箱
- Integer.valueOf(int)及自动装箱内幕
- 谈谈JDK1.5新特性之Integer与int的自动装箱和自动拆箱
- Integer的自动装箱与拆箱
- Integer与int的装箱(缓存)与拆箱
- int Integer 装箱 拆箱 自动装箱 自动拆箱
- Integer 和 int 的区别 (自动装箱 与 拆箱)
- Integer自动拆箱与自动装箱的注意事项
- 自动装箱与自动拆箱(jdk1.5后)(以int和Integer为例)
- Integer自动装箱和Integer.valueOf()
- Integer类自动装箱、拆箱与享元模式
- int与Integer,long与Long的区别以及装箱与拆箱的理解
- java Integer与int的装箱(缓存)与拆箱
- java Integer与int的装箱(缓存)与拆箱
- 关于自动装箱 与自动 和自动拆箱。Integer,Boolean等
- Java中Integer与int类型的装箱和拆箱
- Java中Integer与int类型的比较--装箱和拆箱
- Android中基于RxJava的响应式编程
- 基于jsoup爬虫下载图库
- HttpClient与httpComponents、HttpPost、HttpGet
- iOS字典创建后,没有key。。。
- C++库文件解析(conio.h)
- Integer.valueOf(int i)与自动拆箱与装箱
- csv 读取 邮件附件读取
- Oracle单行函数
- Android获取随机三位数
- 【python新手】---基础算法(1)
- spark streaming 批量索引数据到 elasticsearch
- R语言基本知识梳理(1)-基本管理及向量操作
- Android酷炫实用的开源框架(UI框架)
- ubuntu中通过U盘制作启动盘