Java自动装箱与拆箱
2017-08-22 18:21
344 查看
原博客地址:http://blog.csdn.net/jackiehff/article/details/8509056
1.Java数据类型
在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型。
在Java中,数据类型可以分为两大种,Primitive
Type(基本类型)和Reference Type(引用类型)。基本类型的数值不是对象,不能调用对象的toString()、hashCode()、getClass()、equals()等方法。所以Java提供了针对每种基本类型的包装类型。如下:
Java基本数据类型
(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)拆箱:跟自动装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为基本类型的数据。
如下:
int i = new Integer(2);//这是拆箱
编译器内部会调用int intValue()返回该Integer对象的int值
注意:自动装箱和拆箱是由编译器来完成的,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。
结果:
例二:
第二个例子中,e的初始值与d并不同,因此e与d是各自创建了个对象,(e==d)为false 。
同理可知,第一个例子中的str3与str4也是各自new了个对象,而str1与str2却是引用了同一个对象。
1.Java数据类型
在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型。
在Java中,数据类型可以分为两大种,Primitive
Type(基本类型)和Reference Type(引用类型)。基本类型的数值不是对象,不能调用对象的toString()、hashCode()、getClass()、equals()等方法。所以Java提供了针对每种基本类型的包装类型。如下:
INDEX | 基本类型 | 大小 | 数值范围 | 默认值 | 包装类型 |
1 | boolean | --- | true,false | false | Boolean |
2 | byte | 8bit | -2^7 -- 2^7-1 | 0 | Byte |
3 | char | 16bit | \u0000 - \uffff < 4000 /td> | \u0000 | Character |
4 | short | 16bit | -2^15 -- 2^15-1 | 0 | Short |
5 | int | 32bit | -2^31 -- 2^31-1 | 0 | Integer |
6 | long | 64bit | -2^63 -- 2^63-1 | 0 | Long |
7 | float | 32bit | IEEE 754 | 0.0f | Float |
8 | double | 64bit | IEEE 754 | 0.0d | Double |
9 | void | --- | --- | --- | 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)拆箱:跟自动装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为基本类型的数据。
如下:
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]; 90fd int j = low; for(int k = 0; k <cache.length; k++) cache[k] =new Integer(j++);// -128到high值逐一分配到缓存数组 } private IntegerCache() {}//构造方法,不需要构造什么 }
相关文章推荐
- java自动装箱和拆箱
- java中 interger自动装箱拆箱
- java自动装箱拆箱深入剖析
- java中的自动拆箱、装箱是指什么?
- Java自动拆箱和装箱
- Java 性能笔记:自动装箱/拆箱(转)
- Java中的自动装箱与拆箱
- Java_自动装箱_自动拆箱和String常量池(享员模式应用)
- Java基础知识强化66:基本类型包装类之JDK5新特性自动装箱和拆箱
- day7 常用类字符串处理类--String、StringBuffer、StringBuilder 自动装箱、拆箱 Object类 Java 的异常处理机制
- java自动装箱与拆箱
- java之自动装箱拆箱
- Java 自动装箱与拆箱
- Java语法糖2:自动装箱和自动拆箱
- Java 自动装箱与拆箱(Autoboxing and unboxing)
- Java中的自动装箱与拆箱
- java里重载时的自动装箱与拆箱机制
- java高新技术之自动装箱拆箱
- 说说java的自动装箱(autoboxing)和拆箱(unboxing
- JAVA 自动装箱拆箱