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. 前端Tips#4 - 用 process.hrtime 获取纳秒级的计时精度

    本文同步自 JSCON简时空 - 前端Tips 专栏#4,点击阅读 视频讲解 视频地址 文字讲解 如果去测试代码运行的时长,你会选择哪个时间函数? 一般第一时间想到的函数是 Date.now 或 Da ...

  2. 网络流学习 - dinic

    推荐博客:https://www.cnblogs.com/SYCstudio/p/7260613.html#4246029

  3. 防止过拟合的方法 预测鸾凤花(sklearn)

    1. 防止过拟合的方法有哪些? 过拟合(overfitting)是指在模型参数拟合过程中的问题,由于训练数据包含抽样误差,训练时,复杂的模型将抽样误差也考虑在内,将抽样误差也进行了很好的拟合. 产生过 ...

  4. AVR单片机教程——LCD1602

    本文隶属于AVR单片机教程系列.   显示屏 开发板套件里有两块屏幕,大的是LCD(液晶显示),小的是OLED(有机发光二极管).正与你所想的相反,短小精悍的比较贵,而本讲的主题--LCD1602-- ...

  5. SSAS Tabular表格模型实现动态权限管理

    最近忽然对SSAS产生了浓厚兴趣,我看博客园上也米有写关于SSAS 2016下表格模型实现动态权限管理的文章,最近鼓捣了一下微软的样例,鼓捣好了,把过程中遇到的一些问题写出来,抛砖引玉,也算给自己一个 ...

  6. Nmap使用教程(二)

    TCP空闲扫描 这种先进的扫描方法允许对目标进行一个真正的盲目TCP端口扫描(即没有数据包从你的真实IP地址发送到目标).相反独特的侧信道攻击利用僵尸主机上可预测的IP分段ID序列生成来收集关于目标的 ...

  7. 【python系统学习08】for循环知识点合集

    for循环 for简介 [循环]:就是依照某些我们编写的特定规则,重复的做一件事. 当你需要重复的"搬砖"的时候,可以用for循环进行遍历,让机器循环的帮你去"搬砖&qu ...

  8. 深入Nodejs模块fs - 文件系统操作

    node 的fs文档密密麻麻的 api 非常多,毕竟全面支持对文件系统的操作.文档组织的很好,操作基本分为文件操作.目录操作.文件信息.流这个大方面,编程方式也支持同步.异步和 Promise. 本文 ...

  9. xsd 和 wsdl

    xsd : 可用方便 不同的语言之间的 用命令行来 转换对应语言的. wsdl: 可用方便不同语言的类描述 用命令行 来相互转换. 类似 thift me ?

  10. 对于kvm配置ssh

    首先我们要让自己的机器开启ssh服务 首先更新源 sudo apt-get update 安装ssh服务 sudo apt-get install openssh-server 检测是否已启动 ps ...