在学习Java的基本数据类型过程中,看到别人写的简单程序,对于整型变量的定义,使用不一样的方式,有int、Integer、New Integer,于是心生疑问,难道这些方式等价?于是查了各种博客,明白了其中的区别。下面是对这一部分的总结
参考链接:https://blog.csdn.net/login_sonata/article/details/71001851
首先,我们需要了解Java的数据类型分为两种:一、基本数据类型 二、引用数据类型。 其中基本数据类型包含boolean、byte、int、char、long、short、double、float;引用数据类型包含类、数组、接口。但是Java为了能够将基本数据类型和对象的思想联系,所以又在基本数据类型的基础上引入包装数据类型(wrapper class),对应关系如下:
基本数据类型 | boolean | byte | int | char | long | short | double | float |
包装数据类型 | Boolean | Byte | Integer | Character | Long | Short | Double | Float |
由于Java5.0引入了自动装箱/拆箱(autoboxing)的功能,二者实现了相互转换
自动装箱:将基本数据类型重新转换为对象
Integer num = 10;
//用到了自动装箱,解析为:
Integer num = new Integer(10)
自动拆箱:将对象重新转换为基本数据类型
Integer num = 10;
//进行计算时隐含的有自动拆箱
System.out.print(num--);
下面介绍一下Java对于Integer和int的自动装箱/拆箱设计中的享元模式(flyweight)
在Java中为了加大对简单数字的重复利用,Java定义自动装箱时对于值从-128-127被装箱成Integer对象后,会在内存中被重用,也就是始终存在一个对象。但如果数值在这个范围之外,被装箱后的Integer对象不会被重用,每次装箱都新建一个Integer对象。如果没有自动装箱,那就跟普通的类一样,用new来实例化,每次new产生一个新对象。
最终总结
1.两个通过new产生的Integer变量永远不相等。
Integer i = new Integer(66);
Integer j = new Integer(66);
System.out.print(i == j); //false
原因:Integer变量实际上是对一个Integer对象的引用,new生成的是两个对象,其内存地址不同
2.Integer变量和int变量比较时,只要两个变量的值是相等的,则结果为True
Integer i = new Integer(66);
int j = 66;
System.out.print(i == j); //true
原因:因为包装类Integer和基本数据类型int比较时,包装类会自动拆箱,则实际上就是两个int类型的变量在比较
3.非new生成的Integer变量和new Integer()生成的变量比较结果为false
Integer i = new Integer(66);
Integer j = 66;
System.out.print(i == j); //false
原因:非new生成的Integer变量指向的是Java常量池中的对象,但是new指向的是堆中新建的对象,两者在内存中的地址不同
4.对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false
Integer i = 66;
Integer j = 66;
Integer m = 129;
Integer n = 129;
System.out.print(i == j); //true
System.out.print(m == n); //false
原因:编译时调用的ValueOf()函数,用的是拆箱和装箱中的享元模式,如上所述。
附:Java中常量池的概念,见下面连接