Java之Integer源码

摘要:
如果运行以下代码,Integera=1000,b=1000;System.out。打印ln;//1整数=100,d=100;System.out。打印ln;//21234你将获得伪真的基本知识:我们知道,如果两个引用指向同一个对象,==表示它们相等。如果你看整数。java类,你会发现一个内部私有类IntegerCacheJava,它缓存从-128到127的所有整数对象。所以,所有的小整数都在内部缓存,然后当我们声明类似的东西时——integer=100;当为1时,它实际上在内部执行Integeri=Integer valueOf;1现在,如果我们查看valueOf()方法,我们可以看到publicstaticIntegervalueOf{if(i˃=IntegerCache.low&&ireturnIntegerCache.cache[i+(-IntegerCache.low)];returnnewInteger(i);}12345如果值的范围从-128到127,它将从缓存返回一个实例。整数c=100,d=100;1指向同一对象。

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

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

如果你运行下面的代码

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

你会得到

false
true
  • 1
  • 2

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

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

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

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

Integer c = 100; 
  • 1

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

Integer i = Integer.valueOf(100); 
  • 1

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

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

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

所以…

Integer c = 100, d = 100; 
  • 1

指向了同一个对象。

这就是为什么我们写

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); // 
    } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

译文链接:http://www.codeceo.com/article/why-java-1000-100.html 

免责声明:文章转载自《Java之Integer源码》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇屏幕刷新原理为ssh主机设置别名下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ubuntu16.04 内核源码编译

1)下载 首先看一下自己的内核版本 apt-cache search linux-source下载内核代码:sudo apt-get install linux-source-4.10.0 2)解压: /usr/source/ 目录下解压 tar -jxv -f linux-source-4.10.0.tar.bz2 3)编译 make menuconf...

《python解释器源码剖析》第0章--python的架构与编译python

本系列是以陈儒先生的《python源码剖析》为学习素材,所记录的学习内容。不同的是陈儒先生的《python源码剖析》所剖析的是python2.5,本系列对应的是python3.7,所以某些地方会和原著有出入,另外我在介绍的过程中会穿插大量的python代码,不仅仅是介绍如何实现的,还会使用python实际地对我们的结论进行演示。下面就开始吧。不过在开始分析...

源码分析Kafka 消息拉取流程

本节重点讨论 Kafka 的消息拉起流程。 @ 目录 1、KafkaConsumer poll 详解 1.1 KafkaConsumer updateAssignmentMetadataIfNeeded 详解 1.1.1 ConsumerCoordinator#poll 1.1.2 updateFetchPositions 详解 1.2 消息拉...

react源码解析7.Fiber架构

react源码解析7.Fiber架构 视频课程(高效学习):进入课程 课程目录: 1.开篇介绍和面试题 2.react的设计理念 3.react源码架构 4.源码目录结构和调试 5.jsx&核心api 6.legacy和concurrent模式入口函数 7.Fiber架构 8.render阶段 9.diff算法 10.commit阶段 11.生命...

在Ubuntu-14.04.3配置并成功编译Android6_r1源码

在Ubuntu-14.04.3配置并成功编译Android6_r1源码 折腾了一周,终于把Android6_r1的源码编译成功。先上图,这是在ubuntu中运行的Android模拟器: 由于我是在win8中安装虚拟机VMware,然后在虚拟机中安装Ubuntu进行编译,所以遇到诸多麻烦。如果直接在linux中编译,可能会更顺利。 -----------...

Hive metastore源码阅读(一)

不要问我为什么,因为爱,哈哈哈哈。。。进入正题,最近做项目顺带学习了下hive metastore的源码,进行下知识总结。 hive metastore的整体架构如图: 一、组成结构: 如图我们可以看到,hive metastore的组成结构分为 客户端 服务端 ,那么下来我们逐一进行分析: 1、客户端 从代码的角度来看:尼玛太多了。。我们从入口HIV...