0%

浅谈Integer

前言

本博客主要涉及以下几个内容:

  1. 装箱与拆箱
  2. 装箱生成的Integer在哪里
  3. 案例

装箱与拆箱

  Java中有八种基本数据类型: byte, short, int, long, float, double, char, boolean。这八种基本数据类型对应着八个包装类,基本数据类型转换为包装类叫做装箱,反之叫做拆箱。

为什么要进行装箱和拆箱?

  Java中最主要有三类存储空间: 栈,堆,方法区。栈中存基本数据类型和堆中对象的引用;堆中一般存放运行时的动态数据,最主要有new出来的对象;方法区中存储的数据不是本文的重点,就不细说了,本文只涉及方法区中的常量池,常量池中存储的是常量。
  基本数据类型因为经常被使用,所以为了提高效率,都放在栈中进行运算;但是栈中的数据并不具备持久性,对于Java中同样经常使用的容器,栈中的数据显然不具备放入容器中的资格,因此才有了装箱和拆箱的步骤。JDK5后,Java实现了自动装箱和拆箱。

如何进行装箱和拆箱

  这里不放java反编译后的结果了,直接说结论。只给出intInteger之间的转换。

  • 代码
1
2
Integer in = 9; //装箱
int i = in; //拆箱
  • 装箱调用:Integer in = Integer.valueOf(9)
1
2
3
4
5
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
  • 拆箱调用:int i = in.intValue()
1
2
3
public int intValue() {
return value;
}

装箱生成的Integer去了哪里?

  上面的源码引出了一个新的类IntegerCache, 这个类是Integer类的静态内部类,内部存在三个常量:

1
2
3
static final int low = -128;
static final int high;
static final Integer cache[];

  常量high会在类中的静态代码块中被赋值为127cache[]中存储了value-128 ~ 127Integer包装类。
  由源码可知:当装箱的int值在-128 ~ 127中时,Integer会直接返回常量池中的对象,而这些对象,在Integer类加载的时候就被创建了,因此不会再开辟多余的空间。而当int的值超过范围,则会在堆中重新开辟Integer对象的空间。

案例

1
2
3
4
5
6
7
8
int a = 99;
int b = 128;
Integer A = a;
Integer AA = 99;
Integer B = b;
Integer BB = 128;
System.out.println(AA == A); // true
System.out.println(BB == B); // false

解释:

  1. AAA都指向常量池中的Integer对象
  2. BBB都是在执行装箱操作后new出来的Integer对象,因此地址不同