本帖最后由 大蓝鲸Java 于 2018-7-27 12:10 编辑
自动装箱自动拆箱原理
1.自动装箱与拆箱的定义
自动装箱就是自动将基本数据类型转换为包装类型;拆箱就是自动将包装器类型转换为基本数据类型。
Java中包含8种基础数据类型:byte short int long float double boolean char 。
其中除了int 和 char 其余对应的包装类都是将首字母变成大写
例:long ---> Long
int和char比较特殊,int ---> Integer char ---> Character。
1.1自动装箱
上面的代码 Integer b=a; 将一个基本数据类型赋值给一个引用数据类型,如果没有自动装箱则无法理解。其实这
就是自动装箱的过程。
在自动装箱的过程中,底层调用了Integer.valueOf ( int i ) 方法
Integer b = a;等同于:
Integer b=Integer.valueOf ( a ) 。
下面是对 Integer.valueOf ( int i ) 方法源码:
如果要赋给Integer的值大于-128小于127则从IntegerCache.cache这个数组中获取值。如果不在这个范围之类,
那么则返回一个Integer对象。
所以Integer.valueOf ( a )其实是返回了一个Integer的对象。因此由于自动装箱的存在Integer b=a 这段代码是可以的。也可以简化来写:
Integer b=3,同样这段代码等价于:
Integer b=Integer.valueOf (3 ) ;
[AppleScript] 纯文本查看 复制代码 public static void main(String[] args) {
//定义一个基本数据类型
int a=3;
//定义一个基本数据类型
Integer b=a;
//b是Integer 类定义的对象,直接用int 类型的a赋值
System.out.println(b);
//打印结果为3
}
public static Integer valueOf(int i) {
if (i >= ‐128 && i <= 127)
return IntegerCache.cache[i + 127];
return new Integer(i);
}
那么IntegerCache.cache数组又是什么?我们来看一下源码:
可以看到在静态代码块中,创建了一个长度为256的数组。因为~128到127之间包括0在内一共有256个数。
遍历数组,给数组中的每一个元素创建了一个Integer的对象赋值到数组中。结合下面的valueOf方法可以得出结论,
当需要用到-128到127之间的数时,不会创建对象而是从数组中获取已经创建好的对象。如果超过了这个范围则创建新的Integer对象。
因为在开发中,-128~127使用频率较高所以如此设计可以提高内存使用效率。这个数组我们称之为byte常量池。
1.2自动拆箱
跟装箱相反,将一个对象赋值给一个基本数据类型了。其实上面的代码等同于int a=b.intValue();这个方法很简单,就是返回了value值,然而value又是什么,继续找到Integer的构造方法:value,就是定义 Integer b=new Integer(3) ; 赋的值。
所以Integer也就是一个JavaBean类,里面封装了一个基本数据类型的成员变量
[AppleScript] 纯文本查看 复制代码 int value。
Integer cache[];
static {
cache = new Integer[(127 ‐ (‐128)) + 1];
int j = low;
for(int k = 0; k < cache.length; k++){
cache[k] = new Integer(j++);
}
}
public static void main(String[] args) {
Integer b=new Integer(3);
//b为Integer的对象
int a=b;
//a为一个int的基本数据类型
}
public int intValue() {
return value;
}
public Integer(int value) {
this.value = value;
}
|