Integer缓存机制

总结:

1、jdk1.5对Integer新增了缓存机制,范围在-128-127(这个范围的整数值使用频率最高)内的自动装箱返回的是缓存对象,不会new新的对象,所以只要在缓存范围内值相等自动装箱返回的对象一样。jdk1.6后缓存范围的最大值127可以通过设置jvm的启动参数(-XX:AutoBoxCacheMax=size)调整
2、Integer的缓存只在自动装箱时有效,使用构造器(new)创建的对象不会触发缓存
3、int和Integer比较时不用考虑缓存问题,因为Integer会自动拆箱为int再和int比较,这时只是单纯的比较值是否相等

详解:
针对Integer常见的一个面试题为

Integer i1 = 100;
Integer i2 = 100;
Integer j1 = 200;
Integer j2 = 200;
System.out.println(i1 == i2); // 输出 true
System.out.println(j1 == j2); // 输出 false

我们对于Integer最基本的理解是Integer是int的包装类,是引用数据类型,引用数据类型用==比较的是对象的内存地址。
我们来看i1的创建过程(jdk1.8)
首先会对Integer i1 = 100;自动装箱(其实就是调用valueOf方法),java会把这段编译为Integer i1 = Integer.valueOf(100),可以自行查看class文件验证。
然后再看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);
}

可以清楚的看到是先从IntegerCache取值,IntegerCache.low IntegerCache.high 范围外则直接new对象(new的对象会存在堆内存中)

我们再来看IntegerCache类,IntegerCache为Integer的私有静态类

 /**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache 第一次使用时生效
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. 可通过参数设置最大值
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/ 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的缓存通过for循环创建存放到一个数组中,注释已经解释该数组会在Integer第一次使用时初始化,结合类加载顺序来理解,第一次使用Integer时内部静态类会被初始化,静态代码块会被执行,存到堆中。会有第一次惩罚

jdk1.5源码参考

 private static class IntegerCache {
static final Integer[] cache = new Integer[256]; static {
for (int i = 0; i < cache.length; i++) {
cache[i] = new Integer(i - 128);
}
}
} public static Integer valueOf(int paramInt) {
if ((paramInt >= -128) && (paramInt <= 127)) {
return IntegerCache.cache[(paramInt + 128)];
}
return new Integer(paramInt);
}

Integer与int用==比较时Integer会自动拆箱(调用intValue()方法)为int进行比较
i1 == 100 会编译成 i1.intValue() == 100

其他缓存的对象
这种缓存行为不仅适用于Integer对象。我们针对所有整数类型的类都有类似的缓存机制。
有 ByteCache 用于缓存 Byte 对象
有 ShortCache 用于缓存 Short 对象
有 LongCache 用于缓存 Long 对象
有 CharacterCache 用于缓存 Character 对象
Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 可以通过参数改变范围外,其它的都不行。

参考博文:https://blog.csdn.net/qq_27093465/article/details/52473649

int与Integer(基本类型与包装类型)

Integer是int的包装类型,两者的区别为:

1、int初始值为0,Integer初始值为null,所有的引用类型都为null;

2、Integer为引用类型,对象存放在堆中。int为基本数据类型,对象存放在栈中;

使用包装类的好处:

1、Integer封装了很多处理方法,方便操作,比如进制转化(toBinaryString)、数据类型之间的转化(toString);

2、解决有些类型不支持基础数据类型的情况,比如List只能接收引用类型;

至于何时使用基本数据类型,何时使用包装类型这个就要看具体需求,当只是作为数值不需要更多的操作时用基本类型就可,灵活使用

基本数据类型和对应的包装类
int——Integer
float——Float 
double——Double 
byte——Byte
long——Long
char——Character
boolean——Boolean
short——Short

自动拆装箱(jdk1.5引入)

自动拆箱实际上就是引用类型自动转化成基本数据类型,自动装箱实际上就是基本数据类型自动转化成对应的引用类型

比如创建Integer i = new Integer(100); 可以直接写成Integer i = 100;不需要强转  (自动装箱)

int j = i  基本数据类型j可以直接等于引用类型i  (自动拆箱)

 Integer i = ;
int j = i; /**
* 上面代码编译成class后
*/
Integer i = Integer.valueOf();
int j = i.intValue();

由上可以看出自动装箱实际上就是调用了valueOf方法,自动拆箱调用了intValue方法

 

Integer缓存机制-基本数据类型和包装类型-自动拆装箱的更多相关文章

  1. Java基础(二) 基本类型数据类型、包装类及自动拆装箱

    我们知道基本数据类型包括byte, short, int, long, float, double, char, boolean,对应的包装类分别是Byte, Short, Integer, Long ...

  2. Java的自动拆装箱与Integer的缓存机制

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10832303.html 一:基本类型与包装类型     我们知道,Java有8大基本数据类型,4整2浮1符1 ...

  3. 自动拆装箱(int,Integer)

    包装类型Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个 ...

  4. Java基础进阶:APi使用,Math,Arrarys,Objects工具类,自动拆装箱,字符串与基本数据类型互转,递归算法源码,冒泡排序源码实现,快排实现源码,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    要点摘要 Math: 类中么有构造方法,内部方法是静态的,可以直接类名.方式调用 常用: Math.abs(int a):返回参数绝对值 Math.ceil(double a):返回大于或等于参数的最 ...

  5. Java基本数据类型与包装类型(转)

    基本数据类型的包装类 为什么需要包装类? Java并不是纯面向对象的语言.Java语言是一个面向对象的语言,但是Java的基本数据类型却不是面向对象的.但是我们在实际使用中经常需要将基本数据转化成对象 ...

  6. Integer的缓存和自动拆装箱

    先看一个简单的例子: public class TestInteger { public static void main(String[] args) { System.out.println(&q ...

  7. java中的自动拆装箱与缓存(Java核心技术阅读笔记)

    最近在读<深入理解java核心技术>,对于里面比较重要的知识点做一个记录! 众所周知,Java是一个面向对象的语言,而java中的基本数据类型却不是面向对象的!为了解决这个问题,Java为 ...

  8. 《java入门第一季》之Integer类和自动拆装箱概述

    / * int 仅仅是一个基本类型.int有对应的类类型,那就是Integer.  * 为了对基本数据类型进行更多的操作,更方便的操作,Java就针对每一种基本数据类型提供了对应的类类型--包装类类型 ...

  9. java的数据类型、自动拆装箱、字面量

    java 中的数据类型分为两大类:值类型(基本数据类型)和引用类型(复合数据类型)  值类型分为 1,整数类型(byte,short,int,long) 2,浮点类型(float,double) 3, ...

随机推荐

  1. Visual Studio 2019移除/禁用Live Share按钮

    Visual Studio 2019新增了几个按钮,搜索按钮,Live Share按钮,发送反馈按钮,管理员按钮(即 “Live Share”, “Send Feedback” ,“ADMIN”) L ...

  2. git查看远程仓库和本地的区别

    git diff 你可以用 git diff 来比较项目中任意两个版本的差异. $ git diff master..test 上面这条命令只显示两个分支间的差异,如果你想找出 master , te ...

  3. web网页设计五种布局

    1.大框套小框布局   2.通栏布局   3.导航栏在主视觉下方的布局  4.左中右布局  5.环绕式布局

  4. C++读书笔记

    C与C++的不同点 C++在struct,union中定义的函数叫成员函数,在class中定义的数据叫数据成员 C++引入了三个存取权限的关键字:public,protected,private pu ...

  5. mysql 行增删改查

    一.增 ); ),(); insert into student(name, age) select name, age from info; 二.删 delete from db1; delete ...

  6. Java入门 - 语言基础 - 09.循环结构

    原文地址:http://www.work100.net/training/java-loop.html 更多教程:光束云 - 免费课程 循环结构 序号 文内章节 视频 1 概述 2 while循环 3 ...

  7. python self用法

    在定义类的过程中,无论是显式的创建类的构造方法,还是向类中添加实例方法,都要将self参数作为方法的第一个参数. class Person: def __init__(self): print(&qu ...

  8. [洛谷P4707] 重返现世

    Description 为了打开返回现世的大门,\(Yopilla\) 需要制作开启大门的钥匙.\(Yopilla\) 所在的迷失大陆有 \(n\) 种原料,只需要集齐任意 \(k\) 种,就可以开始 ...

  9. NOI2.5 1817:城堡问题

    描述 1 2 3 4 5 6 7 ############################# 1 # | # | # | | # #####---#####---#---#####---# 2 # # ...

  10. BAT脚本每隔30秒创建一个512兆文件(测试磁盘监控用)

    @echo offsetlocal ENABLEDELAYEDEXPANSIONset /a ii=0 for /l %%i in (1,1,100) do (set /a ii+=1ping -n ...