java int在哪个区_Java-07:int和Integer有什么区别?

7、int 和 Integer有什么区别?

1、数据类型

iint是基本数据类型,保存在栈中;Integer是引用类型,在堆中申请内存存放数据,在栈里申明引用指向堆中的内存地址。

基本数据类型在栈中怎么存储?

int a = 10;

int b = 10;

JVM有一个局部变量表用来保存引用,如上,建立引用a和引用b,再申请两块内存来存放数据,由引用a和引用b指向它们的内存地址。在Java中, "=="符号是用于比较引用的值,这话没毛病。

那引用类型在堆中怎么存储?

Java普通对象在HotSpot虚拟机Java堆中的内存布局大致可分为3个区域:对象头(Header)、实例数据(Instance)和对齐填充(Padding)。

对象头分为两部分:

Mark Word:用于存储对象自身的运行时数据,长度为32bit或者64bit,同时Mark Word被设计成一个有着动态定义的数据结构,以便在极小的空间内存储尽量多的数据,会根据对象的状态复用自己的存储空间 。

类型指针:记录指向它的类型元数据的指针,如果是数组对象,还需要记录它的数组长度。

实例数据:

对象存储有效信息的位置

对其填充:

HotSpot虚拟机要求对象大小必须是8字节的整数倍; So,我们需要把它补齐。

2、Integer和int的关系

Integer是int的包装类,java有8个基本数据类型:byte、int、long、float、double、boolean、char,同时也会有8个包装类。

我们将int转Integer就是装箱,从Integer转int就是拆箱

装箱/拆箱又分为自动和手动,下面是例子:

public class MainTest {

public static void main(String[] args) {

// 手动装箱

Integer c = new Integer(10);

// 自动装箱

Integer d = 10;

// 手动拆箱

int e = c.intValue();

// 自动拆箱

int f = c;

}

}

我们将上述的源代码进行编译后,使用jd-gui工具进行反编译,得到如下结果:

public class MainTest

{

public static void main(String[] paramArrayOfString)

{

Integer localInteger1 = new Integer(10);

Integer localInteger2 = Integer.valueOf(10);

int i = localInteger1.intValue();

int j = localInteger1.intValue();

}

}

我们会得到如下结论:

自动装箱时编译器会调用valueOf(XX)的方法来量基本数据类型转化为对象;

自动拆箱时编译器会调用intValue、doubleValue等方法将对象装换到基本数据类型。

3、缓存池

valueOf(XX)内部是由玄机的,它有一个缓存池,我们先来看下IntegerCache内部类:

private static class IntegerCache {

static final int low = -128;

static final int high;

static final Integer cache[];

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() {}

}

IntegerCache内部的组成不多,我们来看下:

定义了缓存的下限;

static final int low = -128;

定义缓存的上限引用,没有赋值;

static final int high;

定义缓存存放的数据,我们可以看到,缓存就是一个普通的Integer数组;

static final Integer cache[];

我们能看到静态初始语句由如下功能:

先给缓存的上限(high)赋值初始值,但这个值可以被后续读取到配置属性覆盖

从JVM配置中获取缓存上限的值(integerCacheHighPropValue)

选择上限值,从integerCacheHighPropValue,high,Integer.MAX_VALUE - (-low) -1三者选择

h+(-low)+1不能超过Integer.MAX_VALUE

初始化Integer数组

给Integer数组赋初始值

static {

// 1. 先给缓存的上限(high)赋值初始值,但这个值可以被后续读取到配置属性覆盖

int h = 127;

// 2. 从JVM配置中获取缓存上限的值

String integerCacheHighPropValue =

sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");

// 3. 选择上限值,从integerCacheHighPropValue,h,Integer.MAX_VALUE - (-low) -1三者选择

if (integerCacheHighPropValue != null) {

try {

int i = parseInt(integerCacheHighPropValue);

i = Math.max(i, 127);

// h+(-low)+1不能超过Integer.MAX_VALUE

h = Math.min(i, Integer.MAX_VALUE - (-low) -1);

} catch( NumberFormatException nfe) {

}

}

high = h;

// 4. 初始化Integer数组

cache = new Integer[(high - low) + 1];

int j = low;

// 5. 给Integer数组赋初始值

for(int k = 0; k < cache.length; k++)

cache[k] = new Integer(j++);

// 6. 断言判断缓存的上限

assert IntegerCache.high >= 127;

}

我们再来看下valueOf(XX)方法,我们就明白了;

public static Integer valueOf(int i) {

if (i >= IntegerCache.low && i <= IntegerCache.high)

return IntegerCache.cache[i + (-IntegerCache.low)];

return new Integer(i);

}

总结来说: Integer类型的缓存就是一个Integer数组,下限的值为-128(写死),上限的值默认为127,不过我们可以通过配置JVM参数来修改它,只有调用valueOf(XX)方法才能会经过缓存池,也就是手动调用valueOf(XX)或者自动装箱。

缓存上限值是根据需要调整的,JVM 提供了如下参数:

-XX:AutoBoxCacheMax=N

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值