原文:https://www.cnblogs.com/JackPn/p/9392145.html

java有八个基本数据类型,每个都有对应的一个包装类,比如int对应的Integer。从jdk1.5开始,java引入了自动拆装箱,可以直接进行形如Integer i = 20形式的赋值,编译器会自动将其转换为Integer i = Integer.valueOf(20)进行装箱,拆箱则是将int j = i的形式转换成了int j = i.intValue()。

装箱有个细节,如果不注意很容易出错,来看一下:

Integer i = 20;
Integer j = Integer.valueOf(20); System.out.println(i == j);

上面的代码输出为

true

好像没什么问题,那我们形式不变,将数字20换成200,即

i = 200;
j = Integer.valueOf(200);
System.out.println(i == j);

同样的判断,输出变成了:

false

这是为什么呢?

先明确一点,经过编译器编译后,Integer i = 20转换成了Integer i = Integer.valueOf(20),和Integer j = Integer.valueOf(20)的定义完全一样,那为什么将20换成了200后判断结果不一样了呢?
我们来看看Integer.valueOf(int i)方法的内部:

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

可以看出当i在某个区间内时,直接返回了缓存数组IntegerCache.cache中的一个值,超出区间才new一个新的Integer对象。到这里我们大概就可以得出结论:20在缓存范围内所以直接用了缓存,但是200超出了缓存区间所以new了新对象,和原来对象的地址当然不会相同,所以返回false
再来看看IntegerCache,这是一个Integer的私有静态内部类,定义如下:

    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) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low));
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
} private IntegerCache() {}
}

可以看出默认的缓存区间是-128~127,那么什么情况下会修改这个范围呢,修改了某个虚拟机参数的时候,通过代码也可看出,设置的这个缓存上限java.lang.Integer.IntegerCache.high值不能小于127,小于的话就会被赋予127,从而失效。
那么这个值怎么设置呢?我们来看看jdk源码中怎么解释IntegerCache这个静态内部类:

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 -XX:AutoBoxCacheMax= 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.

大概意思是:

将-128到127(包含)的数字做缓存以供自动装箱使用。缓存在第一次使用时被初始化。大小可以由JVM参数-xx:autoboxcachemax=option来指定。JVM初始化时此值被设置成java.lang.Integer.IntegerCache.high属性并作为私有的系统属性保存在sun.misc.vm.class中。

可以得到结论:这个缓存的high值是由JVM参数 -XX:AutoBoxCacheMax= option来指定的。

上述jdk源码来源于jdk1.7,不同版本实现略有不同,但思路一致。

这种共享常用对象的思路有一个名字,叫享元模式,英文名叫Flyweight,即共享的轻量级元素。其他包装类如Boolean、Byte、Short、Long、Charactor都有类似的实现。

java Integer包装类装箱的一个细节的更多相关文章

  1. Java SE之装箱与拆箱【基本数据类型的包装类/==与equals方法】

     对象包装器.自动装箱与拆箱   2016/11/30  晚   特点       1.所有的基本类型都有一个包装器类与之对应.[Integer,Boolean,Long,Character,Shor ...

  2. 再学Java 之 Integer 包装类缓存

    前言:本博文将涉及的Java的自动装箱和自动拆箱,可以参考 这篇文章 和 官方教程 ,这里不再赘述. 首先,先看一个小程序: public class Main { public static voi ...

  3. java基础(七)-----深入剖析Java中的装箱和拆箱

    本文主要介绍Java中的自动拆箱与自动装箱的有关知识. 基本数据类型 基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型.它们是我们编程中使用最频繁的类型. Java是一种强类型 ...

  4. Integer包装类源码分析

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 今天上班的途中在手机里看到几道关于Integer拆装箱的小题目,正好有点时间翻看了一下Integer类的源码,加上自己的一点思考,决定写点 ...

  5. Java知识点梳理——装箱和拆箱

    1.前言:Java是典型的面向对象编程语言,但其中有8种基本数据类型不支持面向对象编程,基本数据类型不具备对象的特性,没有属性和方法:Java为此8种基本数据类型设计了对应的类(包装类),使之相互转换 ...

  6. Java的自动装箱/拆箱

    概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...

  7. 小白学Java:包装类

    目录 小白学Java:包装类 包装类的继承关系 创建包装类实例 自动装箱与拆箱 自动装箱 自动拆箱 包装类型的比较 "=="比较 equals比较 自动装箱与拆箱引发的弊端 自动装 ...

  8. java自动拆装箱

    介绍 Java 5增加了自动装箱与自动拆箱机制,方便基本类型与包装类型的相互转换操作.(关于基本类型与包装类型之前有记录过https://www.cnblogs.com/xiuzhublog/p/12 ...

  9. Java:包装类小记

    Java:包装类 对 Java 中的 包装类 这个概念,做一个微不足道的小小小小记 基本数据&包装类 四类八种基本数据类型: 数据类型 关键字 内存占用 取值范围 字节型 byte 1个字节 ...

随机推荐

  1. Oracle常用sql语句(二)之组函数、多表查询

    DML(数据操纵语言) INSERT .UPDATE. DELETE 插入操作:INSERT: 语法: INSERT INTO 表名(列名1,列名2 ...)VALUES(列值1,列值2...); 注 ...

  2. C#+TaskScheduler(定时任务)实现定时自动下载

    C# /TaskScheduler /定时任务 /定时自动下载 3410 实现原理,客户是广电,在广电服务器创建一个FTP目录,然后每天自动从卫星上自动更新节目列表, 然后功能就是要每天定点一个时间自 ...

  3. js过滤检测敏感词汇

    html: <textarea rows="10" cols="100" id="myDiv"></textarea> ...

  4. JQuery经典总结

    1.jQuery介绍 jQuery是一个js框架(其实就是一个.js文件),它的特点是使用选择器查找要操作的节点,并且将这些节点封装成一个jQuery对象.封装的目的是为了更好地兼容不同的浏览器之间的 ...

  5. STL容器 -- Map

    核心描述: map 就是从键(key) 到 值(value) 的一个映射.且键值不可重复,内部按照键值排序. 头文件: #include <map> 拓展: multimap 是一个多重映 ...

  6. 小程序登陆遇到 ERR_REQUEST_PARAM

    小程序测试环境突然登陆不上,返回的错误信息是{}"code":-1,"error":"ERR_REQUEST_PARAM"}. 小程序登陆代 ...

  7. iOS 9应用开发基础教程下册

    iOS 9应用开发基础教程下册   介绍: 本教程是国内第一本iOS 9开发应用教程.本教程基于Xcode 7.0,使用Swift 2.0语言讲解如何开发iOS 9的应用App. 学习建议:本教程针对 ...

  8. 管理lvm 卷 system-storage-manager

    安装 sudo yum install system-storage-manager [root@si-test-blueking--4 ~]# ssm list 创建物理磁盘到物理卷,<poo ...

  9. sql 和xml

    一·常用基本功能 表结果: 1. 1 <row> 2 <ID>1035</ID> 3 <Rate>6.12</Rate> 4 <Dat ...

  10. 【BZOJ 2024】 2024: [SHOI2009] 舞会 (容斥原理+高精度)

    2024: [SHOI2009] 舞会 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 368  Solved: 102 Description OIto ...