JAVA包装类及其拆箱装箱及Integer类拆装箱的细节


在JAVA中,数据类型可分为两大种,基本数据类型(值类型)和类类型(引用数据类型)。基本类型的数据不是对象,所以对于要将基本数据类型当对象使用的情况,JAVA提供的包装类。基本类型和包装类的对应关系如下:

int -- Integer

char -- Character

double -- Double

float -- Float

byte -- Byte

short -- Short

long -- Long

boolean -- Boolean

所谓装箱,就是把基本类型用他们相对应的引用类型包装起来,使他们可以具有对象的特质,如我们可以把int型包装成Integer类的对象,或者把double包装成Double等等。

所谓拆箱,就是跟装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为值类型的数据。

J2SE5.0后提供了自动装箱和拆箱的功能,此功能事实上是编译器来帮忙,编译器在编译时依照编写的方法,决定是否进行装箱或拆箱动作。

自动装箱的过程:每当需要一种类型的对象时,这种基本来兴就自动的封装到与它相同类型的包装中。

自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动的提取出来,没必要再去调用intValue()和doubleValue()方法。

自动装箱只需将该值赋给一个类型包装器引用,java会自动创建一个对象。例如:

Integer i = 100;//没有通过new建立,java自动完成

自动拆箱只需将该对象值赋给一个基本类型即可。例如:

int i = 10;
Integer j = new Integer(i);//手动装箱操作
int k = j.intValue();//手动拆箱操作

int i = 11;
Integer j = i;//自动装箱
int k = j;//自动拆箱

然而在Integer的自动拆箱会有些细节值得注意:

	public static void main(String[] args) {
		Integer a = 100;
		Integer b = 100;
		
		Integer c = 200;
		Integer d = 200;
		
		System.out.println(a == b); //1
		System.out.println(a == 100); //2
		
		System.out.println(c == d); //3
		System.out.println(c == 200); //4
	}

在java中,“==”是比较object的reference而不是value,自动装箱后,abcd都是Integer这个Object,因此“==”比较的是其引用。按照常规思维,1和3都应该输出false,但结果是:

true

true

false

true

结果2和4,是因为ac进行了自动拆箱,因此其比较是基本数据类型的比较,就跟int比较是一样,“==”在这里比较的是他们的值,而不是引用。对于结果1,虽然比较的时候还是比较对象的引用,但是自动装箱时,java在编译的时候Integer a = 100;被翻译成Integer a = Integer.valueOf(100);关键就在于这个valueOf()的方法。

	public static Integer valueOf(int i) {
		final int offset = -128;
		if (i >= -128 && i <= 127) {
			return IntegerCache.cache[i + offset];
		}
		return new Integer(i);
	}

	private static class IntegerCache {
		private IntegerCache() {
		}
	
		static final Integer cache[] = new Integer[-(-128) + 127 + 1];
		static {
			for (int i = 0; i < cache.length; i++) {
				cache = new Integer(i - 128);
			}
		}
	}

根据上面的jdk源码,java为了提高效率,IntegerCache类中有一个数字缓存了值从-128到127的Integer对象,当我们调用Integer.valueOf(int i)的时候,如果i的值是>=-128且<=127时,会直接从这个缓存中返回一个对象,否则就new一个Integer对象。

下面一段代码:

	public static void main(String[] args) {
		Integer m = new Integer(10);
		Integer n = new Integer(10);
		System.out.println(m == n);

		m = m - 1;
		n = n - 1;
		System.out.println(m == n);
	}

输出结果为:

false

true

原因:m和n都是new出来的对象,内存地址不一样,所以第一次m == n比较的引用不一样。但是m = m - 1首先进行了自动拆箱m.intValue,相减之后在进行装箱的动作:m = Integer.valueOf(m.intValue - 1),而m和n都在-128到127之间,所以自动装箱后,引用的都是缓存内的Integer,所以第二次输出为true.

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值