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

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类之缓存的更多相关文章

  1. Integer类的缓存机制

    一.Integer类的缓存机制 我们查看Integer的源码,就会发现里面有个静态内部类. public static Integer valueOf(int i) { assert IntegerC ...

  2. java Integer类的缓存(转)

    首先看一段代码(使用JDK 5),如下: public class Hello { public static void main(String[] args) { int a = 1000, b = ...

  3. Java Integer类的缓存

    首先看一段代码(使用JDK 5),如下: public class Hello { public static void main(String[] args) { int a = 1000, b = ...

  4. 对Integer类中的私有IntegerCache缓存类的一点记录

    对Integer类中的私有IntegerCache缓存类的一点记录 // Integer类有内部缓存,存贮着-128 到 127. // 所以,每个使用这些数字的变量都指向同一个缓存数据 // 因此可 ...

  5. Integer 中的缓存类 IntegerCache

    我们先看一段代码: public class TestAutoBoxing { public static void main(String[] args) { //-128到127之间 Intege ...

  6. 浅谈 Integer 类

    在讲解 Integer 之前,我们先看下面这段代码: public static void main(String[] args) { Integer i = 10; Integer j = 10; ...

  7. JDK1.8源码(二)——java.lang.Integer 类

    上一篇博客我们介绍了 java.lang 包下的 Object 类,那么本篇博客接着介绍该包下的另一个类 Integer.在前面 浅谈 Integer 类 博客中我们主要介绍了 Integer 类 和 ...

  8. Integer类实现方式和注意事项

    java.lang.Integer类的源代码: //定义一个长度为256的Integer数组 static final Integer[] cache = new Integer[-(-128) + ...

  9. Integer类分析(jdk8)

    一.构造函数 1. Integer类继承Number类,实现Comparable接口,重写了compareTo()方法. 2. Integer最小值为-2147483648,最大值为214748364 ...

随机推荐

  1. shell脚本技巧记录

    2014/4/9 shell脚本变量处理: ${varible##*string} //从左向右截取最后一个string后的字符串 ${varible#*string} //从左向右截取第一个stri ...

  2. python nose测试框架全面介绍七--日志相关

    引: 之前使用nose框架时,一直使用--logging-config的log文件来生成日志,具体的log配置可见之前python nose测试框架全面介绍四. 但使用一段时间后,发出一个问题,生成的 ...

  3. Node学习HTTP模块(HTTP 服务器与客户端)

    Node学习HTTP模块(HTTP 服务器与客户端) Node.js 标准库提供了 http 模块,其中封装了一个高效的 HTTP 服务器和一个简易的HTTP 客户端.http.Server 是一个基 ...

  4. 第一个maven项目

    1.新建maven project 注意:勾上create a new simple project 2.填写相关信息, Grounp id为大项目名字,Artifact id为小项目的名字.注意:P ...

  5. thinkphp---模糊查询详解

    最近做项目,在做搜索模块的时候,模糊查询肯定少不了. 今天就详细的看一下模糊查询: $where['title'] = array('like','%'.$words.'%'); $where['ti ...

  6. 11.23CSS笔记

    每一步的编写过程都在代码里面书写了,暂且记录下来 <!DOCTYPE html> <html lang="en"> <head> <met ...

  7. POJ_2019_Cornfields

    Cornfields Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 7444   Accepted: 3609 Descri ...

  8. traceroute 排查 nginx 反向代理 配置

    [root@b ~]# traceroute www.test.comtraceroute to www.test.com (134.175.58.66), 30 hops max, 60 byte ...

  9. pandas绘图总结

    转自:http://blog.csdn.net/genome_denovo/article/details/78322628 pandas绘图总结 pandas中的绘图函数(更加详细的绘图资料可参考p ...

  10. Celery 分布式任务队列入门

    一.Celery介绍和基本使用 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery ...