前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你真的理解 Integer 的缓存问题吗?

你真的理解 Integer 的缓存问题吗?

作者头像
攻城狮的那点事
发布2019-08-22 18:02:10
1.2K0
发布2019-08-22 18:02:10
举报
文章被收录于专栏:攻城狮的那点事

在开始之前,我们先看看下面给出的这个例子,问输出的结果是多少:

代码语言:javascript
复制
public class IntTest {
    public static void main(String[] args) { 
        Integer a = 100, b = 100, c = 150, d = 150; 
        System.out.println(a == b);
        System.out.println(c == d);
     }
}

很多小伙伴可能非常犹豫,有一些经验的同学可以回答出"标准"答案。

问原因则随口就说”Integer缓存了-128到127之间的整数对象“,为什么会缓存?还有其他答案?可能就不知道了。

what???

难道这不是标准答案?还想咋地?

运行

想知道答案很容易,直接运行,结果如下:

源码法

直接看源码, 我们知道声明整数时,会通过 java.lang.Integer#valueOf(int) 构造(不信可以断点)。

代码语言:javascript
复制
/** 
 * Returns an {@code Integer} instance representing the specified 
 * {@code int} value. If a new {@code Integer} instance is not 
 * required, this method should generally be used in preference to 
 * the constructor {@link #Integer(int)}, as this method is likely 
 * to yield significantly better space and time performance by 
 * caching frequently requested values. 
 * 
 * This method will always cache values in the range -128 to 127, 
 * inclusive, and may cache other values outside of this range. 
 * 
 * @param i an {@code int} value. 
 * @return an {@code Integer} instance representing {@code i}. 
 * @since 1.5 
 */
public static Integer valueOf(int i){
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

通过源码和注释可以看到,如果是-128到127之间的整数,则会使用整数缓存对象,否则就new一个整形对象。

因此第一个是true,第二个是false。

反汇编

前面讲到了,用到了 再问一个问题 为什么调用了 java.lang.Integer#valueOf(int) ?

我们直接反汇编:javap -c IntTest

代码语言:javascript
复制
Compiled from "IntTest.java"
public class com.chujianyun.common.int_test.IntTest {
  public com.chujianyun.common.int_test.IntTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."&lt;init&gt;":()V
       4: return
 
  public static void main(java.lang.String[]);
    Code:
       0: bipush        100
       2: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       5: astore_1
       6: bipush        100
       8: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      11: astore_2
      12: sipush        150
      15: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      18: astore_3
      19: sipush        150
      22: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      25: astore        4
      27: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      30: aload_1
      31: aload_2
      32: if_acmpne     39
      35: iconst_1
      36: goto          40
      39: iconst_0
      40: invokevirtual #4                  // Method java/io/PrintStream.println:(Z)V
      43: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
      46: aload_3
      47: aload         4
      49: if_acmpne     56
      52: iconst_1
      53: goto          57
      56: iconst_0
      57: invokevirtual #4                  // Method java/io/PrintStream.println:(Z)V
      60: return
}

很明显四个Integer对象的构造使用了java/lang/Integer.valueOf函数。

那么除了上面的回答还有哪些更完善的回答呢?

我们继续看 java.lang.Integer.IntegerCache的源码

代码语言:javascript
复制
/**
     * 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=&lt;size&gt;} 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[];
 
// 省略
}

可以看到可以通过设置虚拟机参数:XX:AutoBoxCacheMax=<size>或 -Djava.lang.Integer.IntegerCache.high=<high>

来设置缓存范围的最大值(包含)。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 攻城狮的那点事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档