JDK源码学习——Integer基本数据类的缓存
2011-08-18 17:20
519 查看
1.Integer、Long、Float、Double基本数据类
问题来源:今天偶然看到了Integer.valueOf()方法,而查看资料显示【.valueof()是一个静态方法,同时调用几次该方法来创建Integet对象,最终都是调用到同一个Integer实例。】由于对jdk的api实现不熟悉,所以不明白这些是怎么做到的。因此我编写一个例子进行一下验证:
这种结果正好符合资料上面的描述。当我把a=11;重新设置值时,对象a的实例id变成新的id号了,这样就相当于重新实例了一个Integer对象。
这种现象我没有弄明白,按照正常的思维来分析,a=11;这句代码应该只是把Integer实例中的value属性重设一下值,为什么会重新实例一个新的
Integer对象呢?是在没弄明白,所以只好去查看jdk 1.5 API源代码。
打开Integer类,里面的方法让我大开眼界,发现自己和大师级别人物的差距太大了,所以以后要继续好好学习,追随他们,直至超越(低调...)
根据上面的【问题来源】我有一下几个问题需要通过jdk的源码来解答疑惑。
1.为什么调用a、b、c这三个变量调用Integer.valueof()会得到同一个实例?
2.为什么c=10;也会自动变成一个等同于a、b的实例?
3.为什么执行a=11;之后会产生一个新的Ingeter对象?
抱着疑问去看东西,永远是最有效果的。
打开Integer类,就让我看到了一句代码,不得其解。
这个问题先放下,不影响我对上面三个问题的解答。
问题一解答:
为什么调用Integer.valueof()会得到同一个实例,只好去查找valueof()方法。方法代码如下:
按照源代码的逻辑来推断,只有在数值属于(-128~127)这个范围类的数据,调用Integer.valueof(输入的数值)才会使用缓存中已实例化好的对象。
超出这个范围的数据都是新实例化的对象。接下来就验证这个结论:
Integer e = Integer.valueof(128);
Integer f = Integer.valueof(128);验证发现:果然e、f的实例号不一样。说明不在(-128~127)范围内的数据调用Integer.valueof()是产生新的实例。
自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。在自动装箱时对于值从-128到127之 间的值,它们被装箱为Integer对象后,会存在内存中被重用,所以范例4.6中使用==进行比较时,i1 与 i2实际上参考至同一个对象。如果超过了从-128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象,所以范例4.7使用==进行比较时,i1与i2参考的是不同的对象。所以不要过分依赖自动装箱与拆箱,您还是必须知道基本数据类型与
对象的差异。
问题来源:今天偶然看到了Integer.valueOf()方法,而查看资料显示【.valueof()是一个静态方法,同时调用几次该方法来创建Integet对象,最终都是调用到同一个Integer实例。】由于对jdk的api实现不熟悉,所以不明白这些是怎么做到的。因此我编写一个例子进行一下验证:
Integer a = Integer.valueof(10); Integer b = Integer.valueof(10); Integer c = null; c=10; a=11;最后我在 c = 10;处打下断点,查看各个对象的id号,发现实例a、b、c三个都是同一个实例id号,因此就表示a、b、c 是同一个对象。
这种结果正好符合资料上面的描述。当我把a=11;重新设置值时,对象a的实例id变成新的id号了,这样就相当于重新实例了一个Integer对象。
这种现象我没有弄明白,按照正常的思维来分析,a=11;这句代码应该只是把Integer实例中的value属性重设一下值,为什么会重新实例一个新的
Integer对象呢?是在没弄明白,所以只好去查看jdk 1.5 API源代码。
打开Integer类,里面的方法让我大开眼界,发现自己和大师级别人物的差距太大了,所以以后要继续好好学习,追随他们,直至超越(低调...)
根据上面的【问题来源】我有一下几个问题需要通过jdk的源码来解答疑惑。
1.为什么调用a、b、c这三个变量调用Integer.valueof()会得到同一个实例?
2.为什么c=10;也会自动变成一个等同于a、b的实例?
3.为什么执行a=11;之后会产生一个新的Ingeter对象?
抱着疑问去看东西,永远是最有效果的。
打开Integer类,就让我看到了一句代码,不得其解。
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");4.这句代码的意思不是很清楚,也不知道TYPE到底有啥作用,问题是Class.getPrimitiveClass()这个方法我在jdk1.5 api文档里面都没有找到。
这个问题先放下,不影响我对上面三个问题的解答。
问题一解答:
为什么调用Integer.valueof()会得到同一个实例,只好去查找valueof()方法。方法代码如下:
public static Integer valueOf(int i) { final int offset = 128; if (i >= -128 && i <= 127) { // must cache 该处只能缓存-128~127的数据,超出这个范围的就都是新实例化Ingeter对象。 return IntegerCache.cache[i + offset]; } return new Integer(i); }IntegerCache是Integer类的一个成员内部类,代码如下:
public final class Integer extends Number implements Comparable<Integer> { … … private static class IntegerCache { private IntegerCache(){} static final Integer cache[] = new Integer[-(-128) + 127 + 1];//静态设置一个存储Integer的数组,就是一个cache //初始化这个cache,你会发现这个cache里面只缓存了-128~127这个范围的Integer实例。 static { for(int i = 0; i < cache.length; i++) cache[i] = new Integer(i - 128); } } … … }
按照源代码的逻辑来推断,只有在数值属于(-128~127)这个范围类的数据,调用Integer.valueof(输入的数值)才会使用缓存中已实例化好的对象。
超出这个范围的数据都是新实例化的对象。接下来就验证这个结论:
Integer e = Integer.valueof(128);
Integer f = Integer.valueof(128);验证发现:果然e、f的实例号不一样。说明不在(-128~127)范围内的数据调用Integer.valueof()是产生新的实例。
自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。在自动装箱时对于值从-128到127之 间的值,它们被装箱为Integer对象后,会存在内存中被重用,所以范例4.6中使用==进行比较时,i1 与 i2实际上参考至同一个对象。如果超过了从-128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象,所以范例4.7使用==进行比较时,i1与i2参考的是不同的对象。所以不要过分依赖自动装箱与拆箱,您还是必须知道基本数据类型与
对象的差异。
相关文章推荐
- java核心基础--jdk源码分析学习--基本数据类型
- java核心基础--jdk源码分析学习--Integer
- java学习之旅63常用类_包装类_Integer_Number_JDK源码分析
- [Java]JDK源码学习(2)Integer
- JDK源码分析之Integer
- OpenJDK源码研究笔记(五)-缓存Integer等类型的频繁使用的数据和对象,大幅度提升性能(一道经典的Java笔试题)
- [Java]JDK源码学习(1)ArrayList和Vector
- JDK 1.7 Integer.parseInt 源码解析
- Python源码学习笔记(1 基本数据类型)
- JDK源码分析-Integer
- JDK源码学习(6)-ConcurrentHashMap代码学习
- MySQL的查询缓存机制基本学习教程
- nginx 源码学习(六) 基本数据结构 ngx_array_t
- nginx 源码学习笔记(六)——nginx基本数据结构
- java jdk缓存-128~127的Long与Integer
- JDK源码学习--java.lang.Object类
- 分布式缓存技术redis学习系列(八)——JedisCluster源码解读:集群初始化、slot(槽)的分配、值的存取
- 常用类第十二八课,包装类Integer,Number,JDK源码分析
- JDK源码学习之Arraylist与LinkedList
- jQuery源码学习记录(1)基本结构和选择器