仔细谈一下自动装箱和自动拆箱
1.问:为什么要引入这两个机制?
答:自动装箱和自动拆箱机制是JDK5后被引入的,众所周知java是一种面向对象的语言,一切都以对象(Object)为基础,作为对 象,都可以使用toString(),equals(),hashCode()等方法,在java中分为基本数据类型和引用数据类型,基本数据类型是数值不能调用这些方法,所以如果使用这些方法,就必须把基本数据类型转换为对象,也就是说java为每种基本数据类型提供了对应的封装类。---->这就是自动装箱和自动拆箱。
类型 | 大小 | 数值范围 | 默认值 | 包装类型 |
byte | 1字节,8bit | -2^7~2^7-1 | 0 | Byte |
short | 2字节,16bit | -2^15 -- 2^15-1 | 0 | Short |
int | 4字节,32bit | -2^31 -- 2^31-1 | 0 | Integer |
long | 8字节,64bit | -2^63 -- 2^63-1 | 0 | Long |
float | 4字节,32bit | IEEE 754 | 0.0f | Float |
double | 8字节,64bit | IEEE 754 | 0.0d | Double |
char | 2字节,16bit | \u0000 - \uffff | \u0000 | Character |
boolean | 1字节,8bit | true,false | false | Boolean |
2.概念(前面已经介绍了,这里详细介绍下)
(1)自动装箱:将基本数据类型转换为包装类型,使其能使用对象的一些属性和方法。如 Integer i =3
实际我们执行这句话,在解释器中的执行是:
Integer a=Integer.valueOf(3);
(2)自动拆箱:将包装类型转换为基本数据类型的过程 如:Integer i = new Integer(5);
现在就以Integer和int为例子,详细介绍下这两个的异同。
1.int是基本数据类型,仅仅是一个数值,不能调用toString(),getClass()等方法,Integer是一个包装类,可以调用这些方法。
2.在比较是否相等时,需要分类判断:(这里涉及自动装箱和自动拆箱操作)
首先要介绍下 == 和 equals:两者在基本数据类型的比较中都是比较的数值是否相等,在两个对象的引用的比较中,比较的不止是内容是否相等,还有引用所指向的内存地址是否相等
注意:(1)String类型比较特殊,如果使用语句 String str1 = “str” String str2 = “str” 并且使用== 和 equals比较大小,返回值都是true,这是因为这样在String创建对象时遵循一个原则:只要先前已经创造了相同的对象存储相同的内容,那么再创建引用时并不会再开辟空间创造对象,而是直接将该引用指向已存在的对象,这样地址相同,内容也相同。
但是,如果使用String str1 = new String (“str”) String str2 = new String (“str”) 这样创建的两个引用,同时会各自在堆内存空间中创建各自的对象空间,分别指向,因此内容相同,但是地址不同,
重点来了,使用 == 比较 返回false,
但是,使用equals比较返回的是true,这是因为String是一个类,它重写了equals方法,只要满足内容相同,就可以。
(1)如果两个int类型比较大小,数值相同,使用 == 和 equals 都是返回true。
(2)如果两个Integer类型比较大小,这里还需要细分,具体原因下述
数值返回在-128到127之间的值,只要数值相等,就是相等的(内容和地址都相等)
数值在上述范围之外的,数值相等,但是地址不等。
解释:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
这是jdk中的源码,由此可以看出,在堆内存中创建对象与刚才讲述的String类似,这里,如果使用
自动装箱功能创建并且数值范围在-128到127,之前已经存在相同内容的对象,那么再创建对象引用就会指向堆内存中已存在的,因此地址相同,否则,重新开辟存储空间存储。同理,如果直接使用Integer i1 = new Integer (100),这种与String也类似,地址不同,返回false
(3)如果一个Integer和int类型比较,实际过程是先将Integer
自动拆箱成int类型,然后比较数值大小