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

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. 升级后重启造成fsck.ext3: Unable to resolve UUID

    这篇文章帮了我的大忙了:转载自:http://wilber82.blog.51cto.com/1124820/724472 今天在做服务器补丁部署,有一台ESX4.1的服务器在升级后重启过程中挂了,通 ...

  2. 提交代码到自己的github仓库

    说起来尴尬,好几年前就搞了github建了仓库,当时玩得还有点6,后来一直的公司都是svn,自己业务项目也没玩,都忘了要怎么提交代码到自己的仓库了. 这边再来一波记录吧. 一.配置用户名 git co ...

  3. nginx expires配置

    配置expiresexpires起到控制页面缓存的作用,合理的配置expires可以减少很多服务器的请求要配置expires,可以在http段中或者server段中或者location段中加入   1 ...

  4. MVC验证

    前言 MVC自己的验证机制,通过一个案例记录学习的成果. 首先,model代码如下: public class Students    {        [Display(Name = "I ...

  5. Docker 利用registry创建私有仓库

    一.Docker-registry镜像 下载地址 官方镜像下载比较慢,因为人品问题一直下载不成功,所以选择了国内的镜像. daocloud:   https://hub.daocloud.io/ 还有 ...

  6. Linux 将进程放入后台执行,解决网络,ssh断开导致进程结束(nohup, setsid, &, disown)

    Linux 将进程放入后台执行,解决网络,ssh断开导致进程结束(nohup,  setsid,  &, disown) 1.nohup 命令 我们知道,当用户注销(logout)或者网络断开 ...

  7. linux:文件打包与压缩

    学习内容介绍:Linux 上常用的压缩/解压工具,介绍了zip.rar.tar的使用. 先总结一下常用命令: zip: 打包 :zip something.zip something (目录请加 -r ...

  8. java web启动后执行初始化任务

    写一个类继承ApplicationListener,可以直接引用下述代码,然后调用相应的方法. package com.linewell.system; import com.linewell.cac ...

  9. 发送html内容的email(转)

    html中无法使用css, js.你发送一个<div>片断就好了,不用写整个html页面,因为即使写了,邮件客户端也会删除body之外(包括<body>这个标签)的内容,只留下 ...

  10. Win10系统 Eclipse 下'Publishing to Tomcat'has encountered a problem解决办法

    首先贴出来错误: 详情为:Publishing failedCould not publish to the server.There were issues during deployment to ...