包装类型
数据类型
Java中存在8种基本类型和5种引用类型。
基本数据类型
基本数据类型分为3类:字符,布尔,数值类型
- char:16位
- byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。
- short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
- int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
- long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
- float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
- double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
- boolean:只有true和false两个取值。
对于较小、基础的的变量,作为对象储存不如直接作为值储存在堆栈中
引用数据类型
五种引用类型分别为:
- 类
- 接口
- 数组
- 枚举
- 标注
包装类型的出现
每个基本类型都有对应的包装类型
Java是一个面向对象的语言,基本类型并不具有对象的性质,为了与其他对象“接轨”就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
区别
基本类型的优势:数据存储相对简单,运算效率比较高 包装类的优势:提供对数据更多操作,比如集合的元素必须是对象类型,满足了java一切皆是对象的思想 声明方式不同,基本类型不适用new关键字,而包装类型需要使用new关键字来在堆中分配存储空间; 存储方式及位置不同,基本类型是直接将变量值存储在堆栈中,而包装类型是将对象放在堆中,然后通过引用来使用; 初始值不同,基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null 使用方式不同,基本类型直接赋值直接使用就好,而包装类型在集合如Collection、Map时会使用到
装箱拆箱
装箱即基本类型转为对应包装类型的过程,相应地拆箱即逆过程。
自动拆箱装箱
当对基本类型使用包装类操作或者对包装类进行基本类型操作(如:操作符)时,自动地转换为相应的包装类或基本类型。以达到屏蔽转换的过程,对外只表现为对变量的操作。
JDK源码
使用了了包装类中的newValueOf和xxxValue()方法,也可以由我们自己手动调用,相当于一种语法糖.
缓存机制
以Integer类为例,装箱机制创建包装类对象时,首先会判断数值是否在-128—-127的范围内,如果满足条件,则会从缓存(常量池)中寻找指定数值,若找到缓存,则不会新建对象,只是指向指定数值对应的包装类对象,否则,新建对象。
对应JDK源码为:IntegerCache
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];//声明为final,所以缓存的对象会被放入常量池中;声明为statci,所以是在类加载的时候就创建好了
//创建-128~127的值的包装类对象
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
复制代码
当我们定义两个Integer的范围在【-128—+127】之间,并且值相同的时候,用==比较值为true;
当大于127或者小于-128的时候即使两个数值相同,也会new一个integer,那么比较的是两个对象,用==比较的时候返回false
享元模式,服用常用的变量对象
Integer 、Byte 、Short 、Long 、Character 五大包装类都有缓冲机制,且缓冲的默认值范围都是-128~127
而Float,Double,Boolean 三大包装类并没有缓冲机制。
缓存机制的设计
IntegerCache是Integer的内部类,用来将-128——high之间的对象进行实例化
这边固定了缓存的下限,但是上限可以通过设置jdk的AutoBoxCacheMax参数调整,自动缓存区间设置为[-128,N];
IntegerCache 不会有实例化,它是 private static class IntegerCache,在 Integer 中都是直接使用其 static 方法
近期评论