A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张权 中级黑马   /  2013-1-2 13:12  /  2696 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张权 于 2013-1-2 14:40 编辑

public class IntegerDemo4 {
        public static void main(String[] args) {
                Integer i1 = 100;//Integer i1 = Integer.valueOf(100);
                Integer i2 = 100;
                Integer i3 = 200;
                Integer i4 = 200;
                System.out.println(i1==i2);//true
                System.out.println(i3==i4);//false
        }
}
  关于这个问题,据源码的推测是 i1与i2的值在一个字节范围内,因此没有new ,那么为什么不new , i1==i2是true呢?  之前我 的理解就是,没有NEW,他们都是在缓存里面, 然后我就突发奇想,既然这样,他们比较的是内存
地址,都是在缓存,  那么我定义  i1 =100  i2 = 10 也是在一个字节范围内,那么i1 == i2应该也就是true了,比较地址值嘛,,可事实上是 false,这就说明我之前的理解是错误的,谁能说下自己的理解?

13 个回复

倒序浏览
本帖最后由 马志军 于 2013-1-2 13:26 编辑

小于一个字节的,在缓存里,只有一个,不管i1,还是i2都是一个数
超过一个字节的,用到就在内存里开辟出一个新的整数
一个100,一个10,内存地址肯定不一样啊,一个地址怎么可能有两个值,所以此时i1==i2肯定为false
回复 使用道具 举报
自动装箱嘛,编译器帮你做了new这件事了
回复 使用道具 举报
马志军 发表于 2013-1-2 13:20
小于一个字节的,在缓存里,只有一个,不管i1,还是i2都是一个数
超过一个字节的,用到就在内存里开辟出一个 ...

我不明白的是,如果我这样定义   Integer i1 = 10 , Integer i2 =100 这样比较为什么是false
  它们都在缓存我知道啊, i1 == i2比较的不是引用么?  既然他们同在缓存,我把实体属性给改了,引用没有变啊,那样应该是true才对啊, 事实却是false, 我就像明白我的理解是哪里出问题了?
回复 使用道具 举报
张权 发表于 2013-1-2 13:26
我不明白的是,如果我这样定义   Integer i1 = 10 , Integer i2 =100 这样比较为什么是false
  它们都在 ...

一个i1,一个i2,这不是两个引用嘛。两个不相干的东西,肯定是false。
你是不是认为缓存就只有一个字节的大小?
回复 使用道具 举报
本帖最后由 张权 于 2013-1-2 13:50 编辑
马志军 发表于 2013-1-2 13:29
一个i1,一个i2,这不是两个引用嘛。两个不相干的东西,肯定是false。
你是不是认为缓存就只有一个字节的大 ...

恩!!!  我的理解是缓存可以存一个字节范围内的数据的空间,这些被存的数都是在缓存里面,而缓存的内存地址值(缓存所占这块空间)却是不变的, 所以他存取的数值不一样,但是他的内存地址值是一样的,所以不管他里面存的数据是不是一样,但是内存地址值却是始终不变的,我这样的理解肯定有问题,但就是不知道正确的理解是怎样的?
回复 使用道具 举报
你存了一个1,放缓存里,以后不管建几个1都是用那个1,又存一个2,放缓存里,以后不管怎么用2都是那个2,但跟1没有关系,两者存的地址是不同的。
缓存具体是多少我不清楚,但肯定不是只有一个字节大小。如果只能放一个数那要它能干什么。
回复 使用道具 举报
jdk1.4以后就相继提供了基本数据类型的实例缓存,Integer类缓存值的范围是-128~127,在这个范围的是直接找的自动缓存区的地址值,所以前面两个比较是true。
使用Oracle/Sun JDK 6,在server模式下,使用-XX:AutoBoxCacheMax=NNN参数即可将Integer的自动缓存区间设置为[-128,NNN]。注意区间的下界固定在-128不可配置。
回复 使用道具 举报
马志军 发表于 2013-1-2 14:24
你存了一个1,放缓存里,以后不管建几个1都是用那个1,又存一个2,放缓存里,以后不管怎么用2都是那个2,但 ...

o哦,知道了,谢谢!!!
回复 使用道具 举报
返编译下就看到源码了
回复 使用道具 举报
谢毅 发表于 2013-1-2 14:38
jdk1.4以后就相继提供了基本数据类型的实例缓存,Integer类缓存值的范围是-128~127,在这个范围的是直接找 ...

这便是标准答案么!API文档中可否查看分配的缓存值范围!
回复 使用道具 举报
niexiaolu 发表于 2013-1-2 14:47
这便是标准答案么!API文档中可否查看分配的缓存值范围!

API看不了,你需要去看java的源代码
回复 使用道具 举报
这个就是java里的源代码关于缓存区的
private static class IntegerCache {
        private IntegerCache(){}

        static final Integer cache[] = new Integer[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Integer(i - 128);
        }
    }
回复 使用道具 举报
Integer的缓存范围是-128-127,在这范围内的值一创建就存在缓存区里以后再用valueOf创建那个值的对象实际用的都是同一个,所以地址一样吧,至于楼主说的定义一个100一个10这个跟在不在范围内好像都没啥关系,两个不同的值在缓存区里当然是分开存储了,地址值当然不一样了,用==比较肯定是返回false的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马