黑马程序员技术交流社区

标题: Integer [打印本页]

作者: 烟雾绕    时间: 2015-2-4 23:23
标题: Integer
  今天上课遇到的问题
  Integer i3 = 127;
  Integer i4 = 127;
  System.out.println(i3 == i4);//true
Why?
作者: 以利亚    时间: 2015-2-5 18:49
对于基本数据类型对象,如果在一个字节之内,i3 、i4这俩引用指向的是同一个对象。。。是不会再开辟空间new对象的,太浪费资源,搞一个就好,省事儿
作者: kenfine    时间: 2015-2-5 20:38
Integer i3 = 127;
Integer i4 = 127;
这两条语句已经包含了自动装箱功能调用了Integer中的valueOf(int i)方法,即变成了Integer i3=Integer.valueOf(127);而查阅了API,以下代码可以看看
  1. public static Integer valueOf(int i) {
  2.         assert IntegerCache.high >= 127;
  3.         if (i >= IntegerCache.low && i <= IntegerCache.high)
  4.             return IntegerCache.cache[i + (-IntegerCache.low)];
  5.         return new Integer(i);
  6.     }
复制代码

显然,传入的i会先进行判断,是否在某一范围内。再找找那个内部类IntegerCache,代码如下:
  1. private static class IntegerCache {
  2.         static final int low = -128;
  3.         static final int high;
  4.         static final Integer cache[];

  5.         static {
  6.             // high value may be configured by property
  7.             int h = 127;
  8.             String integerCacheHighPropValue =
  9.                 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
  10.             if (integerCacheHighPropValue != null) {
  11.                 int i = parseInt(integerCacheHighPropValue);
  12.                 i = Math.max(i, 127);
  13.                 // Maximum array size is Integer.MAX_VALUE
  14.                 h = Math.min(i, Integer.MAX_VALUE - (-low));
  15.             }
  16.             high = h;

  17.             cache = new Integer[(high - low) + 1];
  18.             int j = low;
  19.             for(int k = 0; k < cache.length; k++)
  20.                 cache[k] = new Integer(j++);
  21.         }

  22.         private IntegerCache() {}
  23.     }
复制代码

显然,在-128到127的范围内,以上两条语句其实并没有new对象出来,而是共享了同一个引用。
可以试试
Integer i5=new Integer(127);
Integer i6=new Integer(127);
System.out.println(i5==i6);结果是false。
作者: huanxiang0220    时间: 2015-2-5 20:55
Interger是一个封装类,他会自动装箱,变成一个对象,所以这里的i3和i4都是指向了同一个对象127,==比较引用类型时,永远比较的是地址值,所以结果为true
作者: lishuliang28    时间: 2015-2-5 21:43
你在哪里上课呢
作者: Jaybor    时间: 2015-2-5 22:01
-127到+128内的都不生成实例的
作者: 烟雾绕    时间: 2015-2-6 00:23
lishuliang28 发表于 2015-2-5 21:43
你在哪里上课呢

中腾大厦
作者: lishuliang28    时间: 2015-2-6 14:09
烟雾绕 发表于 2015-2-6 00:23
中腾大厦

嗯呢!!!!!1
作者: 万合天宜    时间: 2015-2-6 14:44
你把一个改成128就false了,哈哈
作者: Never、saydie    时间: 2015-2-6 21:21
三楼解答的比较详细,三楼说得对
作者: Piaget    时间: 2015-2-6 21:42
Integer i3 = 127;     Integer i4 = 127;
这两条语句并没有new对象出来,引用了同一个内存地址。

无标题.png (92.01 KB, 下载次数: 47)

内存图

内存图

作者: phil    时间: 2015-2-6 21:50
哈,楼上图片很生动。
作者: lwj123    时间: 2015-2-6 23:02
  1. Integer i = new Integer(127);
  2. 源代码:
  3. public static Integer valueOf(int i) {
  4.         if (i >= IntegerCache.low && i <= IntegerCache.high)//如果i>-128&&i<=127
  5.             return IntegerCache.cache[i + (-IntegerCache.low)];
  6.         return new Integer(i);//超过了127或者小于-128

  7.         /*
  8.         ntegerCache.low:-128
  9.         IntegerCache.high:127       
  10.        
  11.         //是一个数组,静态修饰
  12.         static final Integer cache[];
  13.        
  14.         //给这个数组赋值
  15.         int j = low;
  16.         for(int k = 0; k < cache.length; k++)
  17.             cache[k] = new Integer(j++);
  18.         //该数组在类加载时就已经对每一个值赋值了,范围是-128,127,因为cache是由static修饰所以在这个范围内都是同一个对象
  19.         //超过了127或者小于-128,返回new Integer(i);这是新的对象了,所以才有


  20. Integer i1 = 127;
  21. Integer i2 = 127;
  22. System.out.println(i1.equals(i2));//true
  23. System.out.println(i1==i2);//true
  24. 以上是对这两个结果的源码解释
  25.         */
  26. }
复制代码

作者: lwh316658735    时间: 2015-2-7 13:41
新特性,享元模式。
作者: 邓士林    时间: 2015-2-7 16:51
学习下。不错




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2