为啥100==100是true 1000==1000是false在java中

2020-09-07 09:21发布

2条回答
敦敦宁
2楼 · 2020-09-07 11:45

这是一个挺有意思的讨论话题。

如果你运行下面的代码:

Integer a = 1000, b = 1000;  
System.out.println(a == b);//1
Integer c = 100, d = 100;  
System.out.println(c == d);//2

你会得到

false
true

基本知识:我们知道,如果两个引用指向同一个对象,用==表示它们是相等的。如果两个引用指向不同的对象,用==表示它们是不相等的,即使它们的内容相同。

因此,后面一条语句也应该是false 。

这就是它有趣的地方了。如果你看去看 Integer.java 类,你会发现有一个内部私有类,IntegerCache.java,它缓存了从-128到127之间的所有的整数对象。

所以事情就成了,所有的小整数在内部缓存,然后当我们声明类似——

Integer c = 100;

的时候,它实际上在内部做的是:

Integer i = Integer.valueOf(100);

现在,如果我们去看valueOf()方法,我们可以看到

public static Integer valueOf(int i) {
      if (i >= IntegerCache.low && i
          return IntegerCache.cache[i + (-IntegerCache.low)];
      return new Integer(i);
}

如果值的范围在-128到127之间,它就从高速缓存返回实例。

所以…

Integer c = 100, d = 100;

指向了同一个对象。

这就是为什么我们写

System.out.println(c == d);

我们可以得到true。

现在你可能会问,为什么这里需要缓存?

合乎逻辑的理由是,在此范围内的“小”整数使用率比大整数要高,因此,使用相同的底层对象是有价值的,可以减少潜在的内存占用。

然而,通过反射API你会误用此功能。

运行下面的代码,享受它的魅力吧

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {

      Class cache = Integer.class.getDeclaredClasses()[0]; //1
      Field myCache = cache.getDeclaredField("cache"); //2
      myCache.setAccessible(true);//3

      Integer[] newCache = (Integer[]) myCache.get(cache); //4
      newCache[132] = newCache[133]; //5

      int a = 2;
      int b = a + a;
      System.out.printf("%d + %d = %d", a, a, b); //


靓猴一枚
3楼 · 2021-10-16 16:29

你看到这个标题是不是很惊讶!这不是结果都一样为false的吗

如果是下面代码:母庸质疑 都是new出来的对象 比较的是内存地址值 肯定不一样。


        Integer a = new Integer(100);

        Integer b = new Integer(100);

        System.out.println(a==b);

1

2

3

如果是下面这几行代码:结果确实不是我们想的这样的


        Integer a=100, b=100;

        //结果为true

        System.out.println(a==b);

        Integer c=1000, d=1000;

        //结果为false

        System.out.println(c==d);

1

2

3

4

5

6

为什么结果不一样首先我们得知道java中自动装箱的概念.


什么是自动装箱

自动装箱就是自动将原始类型值转化为integer对象,比如说int 类型转换为integer对象。

因为这里的装箱不是人为转换的所以是自动装箱.

原始类型byte, short, char, int, long, float, double 和 boolean 对应的封装类为Byte, Short, Character, Integer, Long, Float, Double, Boolean。

IntegerCache内部实现了一个Integer的静态常量数组,在类加载的时候,执行static静态块进行初始化-128到127之间的Integer对象,存放到cache数组中。cache属于常量,存放在java的方法区中。

        //这行代码实际上自动装箱就会执行下面的代码

        Integer a=100, b=100;

        Integer b = Integer.valueOf(100);

1

2

3

其次就是在Integer类中有一个静态内部类IntegerCache,直接看源码



    public static Integer valueOf(int i) {

        //判断i是否在-128和127之间,存在则从IntegerCache中获取包装类的实例,否则new一个新实例

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

            return IntegerCache.cache[i + (-IntegerCache.low)];

        return new Integer(i);

    }

    //使用亨元模式,来减少对象的创建(亨元设计模式大家有必要了解一下,我认为是最简单的设计模式,也许大家经常在项目中使用,不知道他的名字而已)

    private static class IntegerCache {

        static final int low = -128;

        static final int high;

        static final Integer cache[];


        //静态方法,类加载的时候进行初始化cache[],静态变量存放在常量池中

        static {

            // high value may be configured by property

            int h = 127;

            String integerCacheHighPropValue =

                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");

            if (integerCacheHighPropValue != null) {

                try {

                    int i = parseInt(integerCacheHighPropValue);

                    i = Math.max(i, 127);

                    // Maximum array size is Integer.MAX_VALUE

                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);

                } catch( NumberFormatException nfe) {

                    // If the property cannot be parsed into an int, ignore it.

                }

            }

            high = h;

            cache = new Integer[(high - low) + 1];

            int j = low;

            for(int k = 0; k < cache>

                cache[k] = new Integer(j++);


            // range [-128, 127] must be interned (JLS7 5.1.7)

            assert IntegerCache.high >= 127;

        }

        private IntegerCache() {}

    }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

通过源码分析原来Integer静态内部类中的代码块预先的对范围[-128—127]的值进行了实例化,这就是为什么第一个结果为true,第二个结果为false。


        Integer a=100, b=100;

        //结果为true

        System.out.println(a==b);

        Integer c=1000, d=1000;

        //结果为false

        System.out.println(c==d);

1

2

3

4

5

6

知道了这些我们对以下困惑就知道为什么了。


        int i = 127;

        int j = 128;

        Integer a = 102;

        Integer b = 102;

        Integer c = 0;

        Integer n = new Integer(102);

        Integer n1 = new Integer(102);

        //基本数据类型比较 值不相等为false

        System.out.println(i==j);

        //int值只要在-128和127之间的自动装箱对象都从缓存中获取的,所以为true

        System.out.println(a==b);

        //数值计算先进行拆箱转换为int类型比较数值 true

        System.out.println(a==b+c);

        //比较的内存地址值 false

        System.out.println(n==n1);

相关问题推荐

  • 回答 9

    按f12没反应的可以选中域名栏,再按就打开了

  • 回答 81
    已采纳

    女生学UI设计或者互联网营销都比较适合些学UI设计,也比较容易上手,经过学习,能快速掌握设计的技能!学互联网营销,比较符合现在的趋势,而且岗位比较多,新媒体,运营,推广等,都是十分不错的选择!...

  • 回答 8

    第一个就是勒,只能选择一个图层预合成的时候用,就是把你现在的图像放到与预合成里面的合成中,而图像上的效果还有调节的变换参数等等,都会应用到预合成上,预合成里面是最原始的图像第二个就是可以选择多个合成进行预合成的,就是把那些图层带效果都放到预...

  • 回答 37

    感觉还是不会消亡吧,打游戏还是网吧更有氛围;而且家里有电脑能上网已经持续了很久的一段时间了,但网吧还是一直存在,说明还是有存在的价值

  • 回答 8

    1、空缺帧的生成方式不同帧采样:在调整视频的播放速度之后,多出来的帧或空缺的帧按现有的帧来生成。光流法:软件根据上下帧来推断像素移动的轨迹,自动生成新的空缺帧。帧混合:混合上下两帧合并生成一个新的帧来填补空缺。2、渲染速度不同帧采样:渲染起来...

  • 回答 18

    一般现在用网易云的比较多

  • 回答 12

    其实wps和office的关系并不存在谁抄袭谁的,给你科普下这两个软件。1.office的前身叫ms-word,1983年发布,是第一个所见即所得的文字编辑器,1985年word登录苹果mac平台。wps1988发布,请不要罔顾事实说office抄袭WPS。2.wps刚发布凭借原生支持中文的优势快速...

  • 回答 35

    在自学之前一定要考虑好以下三个问题学什么?虽说网上有各种各样的教程、攻略,该买什么书,怎么入门,看哪个视频。但对于零基础的小白来讲,面对纷繁复杂的信息,如果不做筛选的话,很容易越看越乱,最后白白浪费了时间。所以,选择自学,首先要有清晰的学习...

  • 回答 11

    实在没办法纠正的话,那就尽量就是自己心态正些,不跟着同事的思维模式考虑问题不要受太大影响不去放在心上就好。

  • 回答 9

    如果同事的作风很过分了,涉及自己的底线了可以直接表明,如果只是自己的心里觉得不爽的话,可以尝试沟通改变一下相处方式。

  • 回答 8

    我觉得以工作为主,尽量不要穿插自己的私人生活情感进去,不然很多事情不是很好处理尤其不要产生情感的纠葛。

  • 回答 2

    编程里面没有空格的东西

  • 回答 6

    当你问这个问题的时候,我就知道你什么都不会!当然,如果你有了很结实的基础的话,还是不知道要怎么编曲,那么,你只有学习!----------首先你得要明白,编曲需要很多的音乐知识!----------在这里询问,你相信你不会得到很好很详细的回答,只有给你许些建议...

  • 小米MIX42021-08-17 15:44
    回答 9

    最近的5G手机市场比较稳定,小米也在这时被爆出了全新5G旗舰消息,并且就是众多米粉们期待的小米MIX4既然是全新的5G旗舰,配置上自然会和当下的潮流结合,带来消费者期待的产品。小米MIX4是小米MIX系列的第四代产品,同时也是首款5G产品,自然在性能方面做到...

  • 回答 11

    基因编辑技术指能够让人类对目标基因进行编辑,实现对特定DNA片段的敲除、加入等。在过去几年中, 以ZFN (zinc-finger nucleases)和TALEN (transcription activator-like effector nucleases)为代表的序列特异性核酸酶技术以其能够高效率地进行定点基因组编辑,...

  • 回答 24

    那是存在电影和电视剧中的,但现实工作中也存在很多it大牛,他们将各种应用发挥到淋漓尽致,不断应用在人们生活中,大数据技术,人工智能等,在生活中越来越科技化,快速化。...

没有解决我的问题,去提问