原创
  • 2020-07-28
  • 浏览 (77)
  • 评论 (0)

Java 装箱拆箱

什么是装箱拆箱

Java中基本数据类型与它们的包装类进行运算时,编译器会自动帮我们进行转换,转换过程对程序员是透明的,这就是装箱和拆箱,装箱和拆箱可以让我们的代码更简洁易懂。

Java中基础数据类型与它们对应的包装类见下表(共8种):

原始类型 包装类型 字节数
boolean Boolean 没有精确定义
byte Byte 1 Byte
char Character 2 Byte
float Float 4 Byte
int Integer 4 Byte
long Long 8 Byte
short Short 2 Byte
double Double 8 Byte

当表格中左边列出的基本类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱。

  • 进行 = 赋值操作(装箱或拆箱)
  • 进行+,-,*,/混合运算 (拆箱)
  • 进行>,<,==比较运算(拆箱)
  • 调用equals进行比较(装箱)
  • ArrayList,HashMap等集合类 添加基础类型数据时(装箱)

自动装箱,拆箱的代码实现

以 int 和 Integer 为例,装箱就是调用 Integer 的 valueOf 方法从缓存中获取一个 Integer 对象 或 new 一个 Integer,拆箱就是调用 Integer 对象的 intValue 方法并赋值返回给 int 。其他基础类型都是大同小异的,具体可以查看源码。

Integer 装箱拆箱

<!--Integer 成员变量-->
private final int value;
<!--装箱-->
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
<!--拆箱-->
public int intValue() {
    return value;
}

Short 装箱拆箱

<!--Short 成员变量-->
private final short value;
<!--装箱-->
public static Short valueOf(short s) {
    final int offset = 128;
    int sAsInt = s;
    if (sAsInt >= -128 && sAsInt <= 127) { // must cache
        return ShortCache.cache[sAsInt + offset];
    }
    return new Short(s);
}
<!--拆箱-->
public short shortValue() {
    return value;
}

Float 装箱拆箱

<!--Float 成员变量-->
private final float value;
<!--装箱-->
public static Float valueOf(float f) {
    return new Float(f);
}
<!--拆箱-->
public float floatValue() {
    return value;
}

结论

以上 Integer 和 Short 的装箱操作都是先从缓存中判断这个值是否在[-128,127]区间,如果在这个区间,直接从缓存中获取,否则 new 一个。通过观察其他包装类型装箱拆箱的源码,并不是所有包装类型都有缓存的机制。

<!--存在缓存机制的包装类型-->
Boolean/Byte/Short/Integer/Long/Character

<!--不存在缓存机制的包装类型-->
Float/Double

注意 Boolean 定义了两个静态常量当做缓存。

public static final Boolean TRUE = new Boolean(true);

public static final Boolean FALSE = new Boolean(false);

可见除了单精度浮点型(Float)和双精度浮点型(Double)没有缓存。其他包装类型都有缓存机制。这是为什么呢?很简单,对于浮点数,100.1与100.2之间有多少个浮点数呢?答案是无数个!所以这里无法像其他包装类型那样做缓存。

正文到此结束
该篇文章的评论功能已被站长关闭
本文目录