JAVA基础整理——IntegerCache

首先要重申下,大家都知道的自动拆箱与自动装箱。即

Interge i=100;

代码实际执行的是

Interge i=Integer.valueOf(100);

此处可以打断点调试验证。

接下来我们看下Integer的valueOf方法中做了什么:

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

此处可以看见,在一定范围内,返回值为IntegerCahce内的缓存,最后以下Integer的内部类IntegerCahce,如下:

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

代码中可见,Integer把-128到127(可通过JVM参数配置进行调整,增大范围)的整数都提前实例化了。所以不管创建多少个这个范围内的Integer用ValueOf出来的都是同一个对象。

但是为什么JDK要这么多此一举呢? 我们仔细想想, 比如订单的交易数量,大多数都是100以内的价格, 一天后台服务器会new多少个这个的Integer, 用了IntegerCache,就减少了new的时间也就提升了效率。同时JDK还提供cache中high值得可配置,

这无疑提高了灵活性,方便对JVM进行优化。

另外,在Long和Short的源码中,jdk也做了同样的优化

参考Long的源码:

private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }

Long也做了缓存,只是没有提供调整机制, 在Short中类似:

private static class ShortCache {
        private ShortCache(){}

        static final Short cache[] = new Short[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Short((short)(i - 128));
        }
    }

原文地址:https://www.cnblogs.com/fbw-gxy/p/11296297.html

时间: 2024-10-22 14:25:39

JAVA基础整理——IntegerCache的相关文章

Java基础整理(1)

1.源代码的文件名必须与公共类(public)的类名一致,而且一个源代码文件中最多只能有一个公共类(public) 2.注释: 3种 行注释  以双斜线  //  开始 段落注释  /*  注释内容  */ 文档注释  /**  注释内容 */ 3.数据类型  8种基本类型 整型 4 种 :  byte(1byte). short(2 bytes). int (4 bytes). long(8 bytes)     均为signed(有符号型) 浮点型 2 种:float(4 bytes).do

Java基础整理(二)

流程控制.异常处理和断言. switch表达式必须是byte.short.int或者char类型,而不是布尔变量. Java的循环语句有for while 和 do..while:while是先判断,do..while是即使是条件表达式为假,循环体至少也执行一次.do..在编制菜单选择时非常有效.for循环的执行过程:[1]执行init部分[2]执行condition部分 真->执行循环体: 假->循环终止[3]增加或者减少循环控制变量的值[4]重复执行 [2]. break和continue

java基础整理总结篇(1)

>>java数据区域,大致分以下几种 寄存器:位于cpu内部,寄存器的数量有限,所以寄存器根据需求分配.不能直接控制它. 堆栈:位于通用RAM(随机访问存储器)中,通过堆栈指针可以从处理器那里获得直接支持.如果堆栈指针向下移动,则分配新的内存:若向上移动,则释放那些内存.这是一种快速有效的分配存储方法,仅次于寄存器.创建程序时,java系统必须知道存储在堆栈内所有项的确切生命周期,以便上下移动堆栈指针.这一约束限制了程序的灵活性,所以虽然某些java数据存储于堆栈中-特别是对象引用,但是jav

JAVA基础整理-21.02Java数字和日期处理

Java生成随机数(random()和random类) 在 java 中要生成一个指定范围之内的随机数字有两种方法:一种是调用 Math 类的 random() 方法,一种是使用 Random 类. Random 类提供了丰富的随机数生成方法,可以产生 boolean.int.long.float, byte 数组以及 double 类型的随机数,这是它与 random() 方法最大的不同之处.random() 方法只能产生 double 类型的 0~1 的随机数. Random 类位于 jav

JAVA基础整理-22. Java内置包装类

Java Object类详解:Object类的常用方法(equals()和getClass()) Object 是 Java 类库中的一个特殊类,也是所有类的父类.当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类. 在 Object 类中定义的方法,在其他类中都可以使用 equals() 方法 equals() 方法的作用与运算符类似,用于值与值的比较和值与对象的比较,而 equals() 方法用于对象与对象之间的比较 getClass() 方法 getClass()

JAVA基础整理-50.Java继承和多态

Java类的封装 封装就是将对象的属性和方法相结合,通过方法将对象的属性和实现细节保护起来,实现对象的属性隐藏. Java类的继承:Java简单的继承及单继承和多继承的区别 简单继承 注意:类的继承并不改变类成员的访问权限.也就是说,如果父类的成员是公有的.被保护的或默认的,它的子类仍具有相应的这些特性. extends 关键字直接跟在子类名之后,其后面是该类要继承的父类名称.例如: public class Student extends Person{} 注意:如果在父类中存在有参的构造方法

JAVA基础整理-80.Java反射机制

Java什么是反射机制?反射机制的概念 在 ORM (Object Relational Mapping 对象关系映射)中间件的实现中,运用 java 反射机制可以读取任意一个 JavaBean 的所有属性,或者给这些属性赋值. Class labelCls=label1.getClass(); //label1为 JLabel 类的对象 Java反射在类中的应用: 通过反射访问构造函数(方法) 为了能够动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个 Constructor 类型的

JAVA基础整理-19.foreach、return、break、continue语句

foreach for(类型 变量名:集合) { 语句块; } foreach 循环语句是 for 语句的特殊简化版本,主要用于执行遍历功能的循环.“类型”为集合元素的类型,“变量名”表示集合中的每一个元素,“集合”是被遍历的集合对象或数组. return return 语句用于终止函数的执行或退出类的方法,并把控制权返回该方法的调用者.如果这个方法带有返回类型,return 语句就必须返回这个类型的值:如果这个方法没有返回值,可以使用没有表达式的 return 语句. 在 switch 语句中

JAVA基础知识整理

一.首先先明白get与post的基本定义和区别: 这是两种在客户端和服务器端进行请求-响应的方法. 1get:从指定的资源请求数据. 2post:向指定的资源提交要处理的数据. get基本上用于从服务器取回数据,注意:get方法可能返回缓存数据. post可以从服务器上获取数据,不过,post方法不会缓存数据,并且常用语连同请求一起发送数据. 二. Jquery $.get()方法. $.get()方法通过Http Get发起请求,从服务器上请求数据. 语法:&.get(URL,callback