关于Java的Integer等类的缓存机制

Java的基础类型

(本文均以局部变量说明情况)

  • 内置数据类型
  • 引用数据类型

内置数据类型

Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。局部变量存储在堆栈中

引用数据类型

在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。

 public static void main(String[] args) {
        int int1 = 1;
        int int2 = 1;
        Integer i1 = 128;
        Integer i2 = 128;
        Integer i3 = 127;
        Integer i4 = 127;
        System.out.println("int1 == int2:1==1-->" + (int1 == int2));
        System.out.println("i1 == i2:128==128-->" + (i1 == i2));
        System.out.println("i3 == i4:127==127-->" + (i3 == i4));
  }

运行结果

自动装箱与拆箱

装箱:将基本类型用它们对应的引用类型包装起来;
拆箱:将包装类型转换为基本数据类型;
举例:

Integer i = 10;  //装箱
int n = i;   //拆箱

字节码文件

   L1

    LINENUMBER 8 L1

    ALOAD 0

    BIPUSH 10

    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;

    PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;

   L2

    LINENUMBER 9 L2

    ALOAD 0

    ALOAD 0

    GETFIELD AutoBoxTest.i : Ljava/lang/Integer;

    INVOKEVIRTUAL java/lang/Integer.intValue ()I

    PUTFIELD AutoBoxTest.n : I

    RETURN

从字节码中,我们发现装箱其实就是调用了 包装类的valueOf()方法,拆箱其实就是调用了 xxxValue()方法。
因此,
Integer i = 10 等价于Integer i = Integer.valueOf(10)
int n = i 等价于int n = i.intValue();

缓存机制

Integer的源码,就会发现里面有个静态类。

  public static Integer valueOf(int i) {
	  //low= -128 
	  //int h = 127;  
	  //high = h -->high=127
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
 
    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() {}
    }
 if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);

从上述代码可以知道 Integer 的值的范围在-128-127之间时,会去IntegerCache中查找对应的数值,但是当时数字超过这个数字在时就会重新创建一个新的Integer类型

而对于IntegerCache类型底层是以Integer cache[]数组实现的 而数组的大小位new Integer[(high - low) + 1],所以Integer具有缓存

Integer的默认缓存范围为-128到127,可以通过jvm参数改变这个范围。

  • 缓存上界high可以通过jvm参数-XX:AutoBoxCacheMax=size指定,取指定值与127的最大值并且不超过Integer表示范围,
  • 下界不能指定,只能为-128。

可以将Integer的缓存机制理解为享元模式,享元模式

其它具有缓存机制的类

实际上不仅仅Integer具有缓存机制,Byte、Short、Long、Character都具有缓存机制。来看看Byte类中的缓存类
在这里插入图片描述
其他的类型不做查看 通过查看源码可以知道
缓存范围为
Integer:−128~127
Byte:−128~127
Short:−128~127
Long:−128~127
Character: 0~127
ASCII码
这写类型内部均是由 XXXCache实现的 内部均是对应的类型数组:如 Byte cache[]; Integer cache[];

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值