Integer类之缓存
在开始详细的说明问题之前,我们先看一段代码

1 public static void compare1(){
2 Integer i1 = 127, i2 = 127, i3 = 128, i4 = 128;
3 System.out.println(i1 == i2);
4 System.out.println(i1.equals(i2));
5 System.out.println(i3 == i4);
6 System.out.println(i3.equals(i4));
7 }

这段代码输出的结果是什么呢?
答案是:
是不是感到奇怪呢?为什么127的时候==是true,128的时候就变成了false?其实要回答这个问题不难。
Integer在赋值的时候会发生自动装箱操作,调用Integer的valueOf方法,那么我们看一下java的源码(1.8):
:

1 /**
2 * Cache to support the object identity semantics of autoboxing for values between
3 * -128 and 127 (inclusive) as required by JLS.
4 *
5 * The cache is initialized on first usage. The size of the cache
6 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
7 * During VM initialization, java.lang.Integer.IntegerCache.high property
8 * may be set and saved in the private system properties in the
9 * sun.misc.VM class.
10 */
11 //注意:此类是静态内部类,而且该类的构造方法是私有,且没有提供实例的静态访问方法,因此该静态内部类是不会有实例的可能,所以只能使用该类提供的静态方法和静态成员变量。
12 private static class IntegerCache {
13 static final int low = -128;
14 static final int high;
15 static final Integer cache[];
16
17 static {
18 // high value may be configured by property
19 int h = 127;
20 String integerCacheHighPropValue =
21 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
22 if (integerCacheHighPropValue != null) {
23 try {
24 int i = parseInt(integerCacheHighPropValue);
25 i = Math.max(i, 127);
26 // Maximum array size is Integer.MAX_VALUE
27 h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
28 } catch( NumberFormatException nfe) {
29 // If the property cannot be parsed into an int, ignore it.
30 }
31 }
32 high = h;
33
34 cache = new Integer[(high - low) + 1];
35 int j = low;
36 for(int k = 0; k < cache.length; k++)
37 cache[k] = new Integer(j++);
38
39 // range [-128, 127] must be interned (JLS7 5.1.7)
40 assert IntegerCache.high >= 127;
41 }
42
43 private IntegerCache() {}
44 }

我们看到IntegerCache的low定义为-128,high默认定义为127.但是high是可以配置的,如果没有配置才是127.我们不去看配置的情况,因为java默认是没有配置的。看一下cache数组,长度为high-low+1,从-128开始到127,存在cache数组内。从上面的代码中可以看出,java在申请一个大于等于-128小于等于127的数时,其实是从cache中直接取出来用的,如果不在这个范围则是new了一个Integer对象。对于==,他比较的是地址。对于int来说比较的是值。对于equals,比较的是内容(要看equals的具体实现)。看一下Integer里面的实现:

1 /**
2 * Compares this object to the specified object. The result is
3 * {@code true} if and only if the argument is not
4 * {@code null} and is an {@code Integer} object that
5 * contains the same {@code int} value as this object.
6 *
7 * @param obj the object to compare with.
8 * @return {@code true} if the objects are the same;
9 * {@code false} otherwise.
10 */
11 public boolean equals(Object obj) {
12 if (obj instanceof Integer) {
13 return value == ((Integer)obj).intValue();
14 }
15 return false;
16 }

而value这是Integer类的成员变量。
而intValue则是Integer类的方法,实现如下:
它比较的确实是值的大小。
因此i1==i2和i1.equals(i2)都是true
i3==i4为false
i3.equals(i4)为true。
Integer类之缓存的更多相关文章
- Integer类的缓存机制
一.Integer类的缓存机制 我们查看Integer的源码,就会发现里面有个静态内部类. public static Integer valueOf(int i) { assert IntegerC ...
- java Integer类的缓存(转)
首先看一段代码(使用JDK 5),如下: public class Hello { public static void main(String[] args) { int a = 1000, b = ...
- Java Integer类的缓存
首先看一段代码(使用JDK 5),如下: public class Hello { public static void main(String[] args) { int a = 1000, b = ...
- 对Integer类中的私有IntegerCache缓存类的一点记录
对Integer类中的私有IntegerCache缓存类的一点记录 // Integer类有内部缓存,存贮着-128 到 127. // 所以,每个使用这些数字的变量都指向同一个缓存数据 // 因此可 ...
- Integer 中的缓存类 IntegerCache
我们先看一段代码: public class TestAutoBoxing { public static void main(String[] args) { //-128到127之间 Intege ...
- 浅谈 Integer 类
在讲解 Integer 之前,我们先看下面这段代码: public static void main(String[] args) { Integer i = 10; Integer j = 10; ...
- JDK1.8源码(二)——java.lang.Integer 类
上一篇博客我们介绍了 java.lang 包下的 Object 类,那么本篇博客接着介绍该包下的另一个类 Integer.在前面 浅谈 Integer 类 博客中我们主要介绍了 Integer 类 和 ...
- Integer类实现方式和注意事项
java.lang.Integer类的源代码: //定义一个长度为256的Integer数组 static final Integer[] cache = new Integer[-(-128) + ...
- Integer类分析(jdk8)
一.构造函数 1. Integer类继承Number类,实现Comparable接口,重写了compareTo()方法. 2. Integer最小值为-2147483648,最大值为214748364 ...
随机推荐
- sencha touch list ListPaging使用详解
示例代码: Ext.define('app.view.message.List', { alternateClassName: 'messageList', extend: 'Ext.List', x ...
- linux下的一些操作命令
1.切换到root账号下: su root 输入密码: 2.修改root账号密码: sudo passwd root 输入密码: 3.cat用法: 查看文件内容 cat 文件名 创建文件 ...
- Pry的安装
Pry 用于rails应用的调试 在Gemfile中添加 gem 'pry', :group =>:development bundle install 即可.pry代替irb方法,直接运行: ...
- Docker 启动 Centos 镜像 提示"Error response from daemon: No command specified"
奇怪的是当我执行启动其他的镜像的时候并没有报错,找了半天资料发现在启动centos这个镜像的时候需要在docker命令后面指定命令参数“/bin/bash”
- cadence allegro 封装产考原点修改
打开 dra文件后 在菜单栏 setup - change drawing origin 在命令栏输入 新的参考点位置 如想更改新坐标位置为 1,2 .输入 x 1 2 上面两步操作后即可修改!
- 如何使用Jquery 引入css文件
如何使用Jquery 引入css文件: $("head").append("<link>");var toolbarCss = $("he ...
- ssh连接超时时间(ssh timeout)的设置方法
问题:当某台远程主机宕机时,ssh远程过去会耗费很多的时间去连接,结果还是会失败. 这个时候可以设置超时时间 ssh -o ConnectTimeout= 192.168.0.10
- gzip: stdin:unexpected end of file
原因是文件下载的不完整,重新下载就好了,
- jQuery将时间转化为时间戳或将时间戳转化为时间
下面的这段代码,是可以将时间戳转为时间,或者将时间戳转为时间: <script type="text/javascript"> $.extend({ myTime:{ ...
- .Net Identity OAuth 2.0 SecurityStamp 使用
起源: 近期帮别人做项目,涉及到OAuth认证,服务端主动使token失效,要使对应用户不能再继续访问,只能重新登陆,或者重新授权. 场景: 这种场景OAuth2.0是支持的,比如用户修改了密码,那所 ...