• 【疑问解决】在自动装箱中Integer赋予一个常量1,为什么会出现==判断true和flase的情况(JDK源码、内部缓冲)


    目录

    解答:

    1.if语句内的low和high值

    2.if块内return的东西

    3.if语句块外的

    总结

    题目代码

    JDK源码有关源码


    问题来源自讲课时的Integer练习中

    当时第一反应是false        true        true

    因为第一段的输出为flase毋庸置疑了,因为已经new了两个新的堆空间,当然指向不同的空间了

    但是第二段第三段就没有头绪了,自动装箱了难道不是执行同一个空间吗 。

    实际上要看自动装箱时的隐式调用Integer.valueOf的源代码

    解答:

            输出为false true true

            第一段是对的,但第二端隐式调用了Integer的valueOf方法,使用debug可以追入

    1.if语句内的low和high值

            进入该方法后,可以看到有if语句分别判断执行两个return,先看if里面的

    if (i >= IntegerCache.low && i <= IntegerCache.high)

            这一句话里面的IntegerCache.low和.high是谁呢?接着追入可以发现

            这个low和high在本类开头已经声明了,而且是静态的,在类加载的时候就已经赋值完毕了,low=-128。

             这段源码重要的是看if语句有没有执行,而在这个if语句块内,执行的是判断有没有在虚拟机初始化时设置初始值,如果没有设置初始值,将默认为空,因为getSavedProperty方法返回java.lang.String为空

    1. String integerCacheHighPropValue =
    2. sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");

             调用虚拟机的获取设置,编译时不输入就为空

    public static java.lang.String getSavedProperty(java.lang.String s) { /* compiled code */ }

             为空不执行if语句high被赋予默认值127,所以min = -128,high = 127

    2.if块内return的东西

            到目前为止,我们解决了if判断是从-128 && 127的值(127可以通过jvm设置)

            接下来探讨return后面的一串是什么东西

            首先是cache,我们可以发现格式是一个数组,使用查找可以找到在本来开头定义了一个对象数组

            注意,这里的对象是static的,所以在类加载的时候编创建好了,我们再找找该静态对象在哪里被赋值或者创建

            查找可以发现,cache数组对象在类被调用时创建了个大小为127+128+1大小的数组,通过for循环赋值从j++也就是-128 ++直到255,这时的k循环从0~255,数值大小循环为-128到127。

             随后if语句块内的就很好理解了,cache已经是静态对象而且被创建好了,直接返回对应的数值的数组对象下标回去即可,这一个机制也叫JDK的内部缓冲

            

    3.if语句块外的

            这个就没什么好解释的了,在-128到127范围之外的我简单粗暴的new一个int i 的值的对象返回给你就行了

    更多关于该JDK内部缓冲的分析请参考

    OpenJDK源码研究笔记(五)-缓存Integer等类型的频繁使用的数据和对象,大幅度提升性能(一道经典的Java笔试题)_51CTO博客_openjdk使用

    总结

            因为题目的第二段我们赋的值是int常量,使用自动装箱隐式调用valueOf方法,在该方法内if判断为真,返回静态对象cache[129] = Interger(1)回去,所以此时的m指向Interger(1)对象,然后第二句同理,n也指向Interger(1)对象,所以sout(m == n)打印为true

            然后第三段,前面的都同理,但x和y都不在-128~127内在if判断时为假,直接new一个新空间,所以x和y当然执行两个不同的新空间,所以==为false

            所以正确答案为 false true flase,完毕

    题目代码

    1. /**
    2. * @author 银海
    3. * @version 1.0
    4. */
    5. public class WrapperExercise02 {
    6. public static void main(String[] args) {
    7. Integer i = new Integer(2);
    8. Integer j = new Integer(1);
    9. System.out.println(i == j); //False
    10. //所以,这里主要是看范围 -128 ~ 127 就是直接返回
    11. /*
    12. 老韩解读
    13. //1. 如果i 在 IntegerCache.low(-128)~IntegerCache.high(127),就直接从数组返回
    14. //2. 如果不在 -128~127,就直接 new Integer(i)
    15. public static Integer valueOf(int i) {
    16. if (i >= IntegerCache.low && i <= IntegerCache.high)
    17. return IntegerCache.cache[i + (-IntegerCache.low)];
    18. return new Integer(i);
    19. }
    20. */
    21. Integer m = 1; //底层 Integer.valueOf(1); -> 阅读源码
    22. Integer n = 1;//底层 Integer.valueOf(1);
    23. System.out.println(m == n); //T
    24. //所以,这里主要是看范围 -128 ~ 127 就是直接返回
    25. //,否则,就new Integer(xx);
    26. Integer x = 128;//底层Integer.valueOf(1);
    27. Integer y = 128;//底层Integer.valueOf(1);
    28. System.out.println(x == y);//False
    29. }
    30. }

    JDK源码有关源码

    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=} 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. private static class IntegerCache {
    12. static final int low = -128;
    13. static final int high;
    14. static final Integer cache[];
    15. static {
    16. // high value may be configured by property
    17. int h = 127;
    18. String integerCacheHighPropValue =
    19. sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
    20. if (integerCacheHighPropValue != null) {
    21. try {
    22. int i = parseInt(integerCacheHighPropValue);
    23. i = Math.max(i, 127);
    24. // Maximum array size is Integer.MAX_VALUE
    25. h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
    26. } catch( NumberFormatException nfe) {
    27. // If the property cannot be parsed into an int, ignore it.
    28. }
    29. }
    30. high = h;
    31. cache = new Integer[(high - low) + 1];
    32. int j = low;
    33. for(int k = 0; k < cache.length; k++)
    34. cache[k] = new Integer(j++);
    35. /**
    36. * Returns an {@code Integer} instance representing the specified
    37. * {@code int} value. If a new {@code Integer} instance is not
    38. * required, this method should generally be used in preference to
    39. * the constructor {@link #Integer(int)}, as this method is likely
    40. * to yield significantly better space and time performance by
    41. * caching frequently requested values.
    42. *
    43. * This method will always cache values in the range -128 to 127,
    44. * inclusive, and may cache other values outside of this range.
    45. *
    46. * @param i an {@code int} value.
    47. * @return an {@code Integer} instance representing {@code i}.
    48. * @since 1.5
    49. */
    50. public static Integer valueOf(int i) {
    51. if (i >= IntegerCache.low && i <= IntegerCache.high)
    52. return IntegerCache.cache[i + (-IntegerCache.low)];
    53. return new Integer(i);
    54. }
    55. /**
    56. * The value of the {@code Integer}.
    57. *
    58. * @serial
    59. */
    60. private final int value;
    61. /**
    62. * Constructs a newly allocated {@code Integer} object that
    63. * represents the specified {@code int} value.
    64. *
    65. * @param value the value to be represented by the
    66. * {@code Integer} object.
    67. */
    68. public Integer(int value) {
    69. this.value = value;
    70. }
    71. }

  • 相关阅读:
    这是什么是
    react事件系统(新版本)
    开会总结【1】ADL129
    yolov
    深入理解Java IO流(第二篇)
    计算机毕业设计Python+djang企业it资产管理系统(源码+系统+mysql数据库+Lw文档)
    计算机网络笔记 第三章数据链路层
    代码优化工具-测试程序执行时间-IDEAdebug+StopWatch
    数学建模学习(100):交通运输问题建模
    2023NOIP A层联测18 划分
  • 原文地址:https://blog.csdn.net/qq_41891655/article/details/134083610