澳门新浦京8455com一个挺有意思的Java技术讨论

澳门新浦京8455com 6

本文由码农网 –
小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

英文原文:
https://dzone.com/articles/why-1000-1000-returns-false-but-100-100-returns-tr

亦枫译文:
http://www.jianshu.com/p/877f0a8a9607

为什么Java中1000==1000为false而100==100为true?

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

澳门新浦京8455com 1

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

如果你运行下面的代码

Java.jpg

如果你运行下面的代码:

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

这是一个非常有意思并且值得讨论的话题。

澳门新浦京8455com 2

你会得到

如果你运行下面的代码:

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

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

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

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

你将得到这样的结果:

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

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

fasle
true

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

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

先了解一下基础知识:我们知道,如果两个引用指向相同的对象,它们在 ==
表达式中是相等的;如果两个引用指向不同的对象,尽管它们拥有相同的内容即值,在
== 表达式中也是不相等的。

澳门新浦京8455com 3

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

所以,按道理,上面第二条语句也应该返回 false 。

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

Integer c = 100;

这就是它有意思的地方了。如果你去翻阅 Java 源代码,查看 Integer.java
类的话,你会发现在这个类里面有一个内部私有类 —— IntegerCache.java
,这个内部私有类缓存了数值为 -128 到 127 之间所有的整型对象。

澳门新浦京8455com 4

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

那么原理就搞清楚了,所有的小整数都被缓存到内部,然后当我们类似这样定义的时候
——

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

Integer i = Integer.valueOf(100);
Integer c = 100;

所以…

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

它在内部做了如下处理:

澳门新浦京8455com 5

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

我们可以得到true。

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

如果我们继续翻阅 valueOf() 的源代码,将会看到 ——

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

所以…

 public static Integer valueOf(int i) {    
        return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
}

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

Integer c = 100, d = 100;

如果数值处于 -128 到 127 之间,它将返回缓存中的实例。

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

指向了同一个对象。

所以…

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

这就是为什么我们写

Integer c = 100, d = 100;

澳门新浦京8455com 6

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

从根本上来讲,指向了相同的对象。

分享一个Java学习裙 六七八,二四一,五六三
每天晚上20:00都会开直播给大家分享Java知识和路线方法,裙里会不定期更新最新的教程和学习方法(进群送2018
Java学习教程),大家都是学习Java的,或是转行,或是大学生,还有工作中想提升自己能力的Java党,如果你是正在学习Java的小伙伴可以加入学习。最后祝所有程序员都能够走上人生巅峰,让代码将梦想照进现实,非常适合新手学习,有不懂的问题可以随时问我,工作不忙的时候希望可以给大家解惑

我们可以得到true。

这就是为什么如果我们这样写:

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

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); //
    }

然而,通过使用反射API,你可能会滥用这个功能。

运行下面一段代码,并且享受它的魅力吧

public static void main(String[] args) throws  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); //

 }
You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图