Java自动装箱与拆箱

原博客地址:http://blog.youkuaiyun.com/jackiehff/article/details/8509056

1.Java数据类型

       在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型。

       在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference Type(引用类型)。基本类型的数值不是对象,不能调用对象的toString()、hashCode()、getClass()、equals()等方法。所以Java提供了针对每种基本类型的包装类型。如下:

Java基本数据类型
INDEX
基本类型
 大小
数值范围
默认值
包装类型
1boolean
   ---true,false
false
Boolean
2byte
8bit-2^7 -- 2^7-1
0Byte
3char
16bit
\u0000 - \uffff
\u0000
Character
4short
16bit
-2^15 -- 2^15-1
0Short
5int 
32bit-2^31 -- 2^31-1
0Integer
6long
64bit-2^63 -- 2^63-1
0Long
7float 
32bit
IEEE 754
0.0fFloat
8double 
64bit
IEEE 754
0.0dDouble
9void
    ---    ------Void

2.Java自动装箱和拆箱定义

       Java 1.5中引入了自动装箱和拆箱机制:

       (1)自动装箱把基本类型用它们对应的引用类型包装起来,使它们具有对象的特质,可以调用toString()hashCode()getClass()equals()等方法。

        如下:

        Integer a=3;//这是自动装箱

        其实编译器调用的是static Integer valueOf(int i)这个方法,valueOf(int i)返回一个表示指定int值的Integer对象,那么就变成这样: 

        Integer a=3;   =>    Integer a=Integer.valueOf(3);

        (2)拆箱自动装箱的方向相反,将IntegerDouble这样的引用类型的对象重新简化为基本类型的数据。

         如下:

         int i = new Integer(2);//这是拆箱

         编译器内部会调用int intValue()返回该Integer对象的int值

         注意:自动装箱和拆箱是由编译器来完成的,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。

3.例子

例一  
	Integer integer1 = 100;  
	Integer integer2 = 100;  
	System.out.println("integer1==integer2: " + (integer1 == integer2));// true  自动装箱的两个缓存中的 Integer对象的引用比较  
	System.out.println("integer1.equals(integer2): " + (integer1.equals(integer2)));// true  
	System.out.println("integer1.compare(integer2): " + integer1.compareTo(integer2));// 0      
	Integer integer3 = 200;  
	Integer integer4 = 200;  
	System.out.println("integer3==integer4: " + (integer3 == integer4));// false 自动装箱的两个new Integer的引用比较  
	System.out.println("integer3>integer4: " + (integer3 > integer4)); // false 将两个对象拆箱,再比较大小  
	System.out.println("integer3.equals(integer4): " + (integer3.equals(integer4)));// true  
	System.out.println("integer3.compare(integer4): " + integer3.compareTo(integer4));// 0     
	Integer integer5 = new Integer(100);  
	Integer integer6 = new Integer(100);  
	System.out.println("integer5==integer6: " + (integer5 == integer6)); // false 两个不同的Integer对象引用的比较  
	System.out.println("integer5.equals(integer6): " + (integer5.equals(integer6)));// true  
	System.out.println("integer5.compare(integer6): " + integer5.compareTo(integer6));// 0      
	int int1 = 100;  
	System.out.println("integer1==int1: " + (integer1 == int1));// true  Integer缓存对象拆箱后与int比较  
	System.out.println("integer1.equals(int1): " + (integer1.equals(int1)));// true  
	System.out.println("integer1.compare(int1): " + integer1.compareTo(int1));// 0        
	int int2 = 200;  
	System.out.println("integer3==int2: " + (integer3 == int2));// true  Integer对象拆箱后与int比较  
	System.out.println("integer3.equals(int2): " + (integer3.equals(int2)));// true  
	System.out.println("integer3.compare(int2): " + integer3.compareTo(int2));// 0   
结果:


例二:

	String str1 ="abc";
	String str2 ="abc";
	System.out.println(str2==str1); //输出为 true 
	System.out.println(str2.equals(str1)); //输出为 true  
	String str3 =new String("abc");
	String str4 =new String("abc"); 
	System.out.println(str3==str4); //输出为 false 
	System.out.println(str3.equals(str4)); //输出为 true
	String d ="2"; 
	String e ="23";
	e = e.substring(0, 1);
	System.out.println(e.equals(d)); //输出为 true 
	System.out.println(e==d); //输出为 false
第二个例子中,e的初始值与d并不同,因此e与d是各自创建了个对象,(e==d)为false 。

同理可知,第一个例子中的str3与str4也是各自new了个对象,而str1与str2却是引用了同一个对象。


4.源码分析

4.1 valueOf工厂方法

public static Integer valueOf(inti) {    
    if(i >= -128 &&i <=IntegerCache.high)    
       //如果i在-128~high之间,就直接在缓存中取出i的Integer类型对象  
       return IntegerCache.cache[i + 128];    
    else  
       return new Integer(i); //否则就在堆内存中创建   
}    

    4.2 IntegerCache内部类

   Integer源码中是怎么在内部缓存数值的。

private static class IntegerCache {//内部类,注意它的属性都是定义为static final  
    static final inthigh; //缓存上界  
    static final Integer cache[];//cache缓存是一个存放Integer类型的数组  
  
    static {//静态语句块  
        final int low = -128;//缓存下界,值不可变  
  
        // high value may beconfigured by property  
        int h = 127;// h值,可以通过设置jdk的AutoBoxCacheMax参数调整(参见(3))  
        if (integerCacheHighPropValue !=null) {  
            // Use Long.decode here to avoid invoking methods that  
            // require Integer's autoboxing cache to be initialized  
            // 通过解码integerCacheHighPropValue,而得到一个候选的上界值  
            int i = Long.decode(integerCacheHighPropValue).intValue();  
            // 取较大的作为上界,但又不能大于Integer的边界MAX_VALUE  
            i = Math.max(i, 127);//上界最小为127  
            // Maximum array size is Integer.MAX_VALUE  
            h = Math.min(i, Integer.MAX_VALUE - -low);  
        }  
        high = h; //上界确定,此时high默认一般是127  
        // 创建缓存块,注意缓存数组大小  
        cache =new Integer[(high - low) + 1];  
        int j = low;  
        for(int k = 0; k <cache.length; k++)  
            cache[k] =new Integer(j++);// -128到high值逐一分配到缓存数组  
    }  
  
    private IntegerCache() {}//构造方法,不需要构造什么  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值