先来看一段程序,如下:

  1. package basic;
  2.  
  3. import java.lang.reflect.Field;
  4.  
  5. public class TestField {
  6.  
  7. public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
  8. @SuppressWarnings("rawtypes")
  9. Class cache = Integer.class.getDeclaredClasses()[0];
  10. Field myCache = cache.getDeclaredField("cache");
  11. myCache.setAccessible(true);
  12. Integer[] newCache = (Integer[]) myCache.get(cache);
  13. newCache[132] = newCache[133];
  14. int a = 2;
  15. int b = a + a;
  16. System.out.printf("%d + %d = %d", a, a, b);
  17. }
  18. }

程序正常运行,输出如下结果:

  1. 2 + 2 = 5

分析:

  1. package basic;
  2.  
  3. /**
  4. * 类TestDeclaredClass.java的实现描述:getDeclaredClasses() 方法返回一个Class对象,包括公共,保护,默认(包)访问的私有类和类中声明的接口的数组,但不包括继承的类和接口。
  5. * 如果类没有声明的类或接口的成员,或者如果此Class对象表示一个基本类型,此方法返回一个长度为0的数组。
  6. *
  7. * @author 2016年6月16日 上午10:17:51
  8. */
  9. public class TestDeclaredClass {
  10.  
  11. public static void main(String[] args) {
  12. try {
  13. Class cls = TestDeclaredClass.class;
  14. Class[] clss = cls.getDeclaredClasses();
  15. for (int i = 0; i < clss.length; i++) {
  16. System.out.printf("CLASS = %s \n", clss[i].getName());
  17.  
  18. }
  19. } catch (SecurityException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23.  
  24. public class InnerClass1 {
  25.  
  26. public InnerClass1(){
  27. System.out.println("InnerClass1");
  28. }
  29. }
  30.  
  31. public interface Inner {
  32. }
  33.  
  34. public class InnerClass2 {
  35.  
  36. public InnerClass2(){
  37. System.out.println("InnerClass2");
  38. }
  39. }
  40.  
  41. private class InnerPrivateClass {
  42.  
  43. public InnerPrivateClass(){
  44. System.out.println("InnerPrivateClass");
  45. }
  46. }
  47. }
  48.  
  49. class MyTestDeclaredClass extends TestDeclaredClass {
  50. }

程序正常运行,输出如下结果:

  1. CLASS = basic.TestDeclaredClass$Inner
  2. CLASS = basic.TestDeclaredClass$InnerClass1
  3. CLASS = basic.TestDeclaredClass$InnerClass2
  4. CLASS = basic.TestDeclaredClass$InnerPrivateClass

接着再看:

  1. package basic;
  2.  
  3. import java.lang.reflect.Field;
  4.  
  5. /**
  6. * 类TestGetDeclaredField.java的实现描述:getDeclaredField() 方法返回一个Field对象,它反映此Class对象所表示的类或接口的指定已声明字段。
  7. * name参数是一个字符串,指定所需字段的简单名称。
  8. *
  9. * @author 2016年6月16日 上午10:36:21
  10. */
  11. public class TestGetDeclaredField {
  12.  
  13. Long size;
  14.  
  15. public TestGetDeclaredField(Long size){
  16. super();
  17. this.size = size;
  18. }
  19.  
  20. public static void main(String[] args) {
  21. try {
  22. Class cls = TestGetDeclaredField.class;
  23. Field field = cls.getDeclaredField("size");
  24. System.out.println("Field = " + field.toString());
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }

程序正常运行,输出如下结果:

  1. Field = java.lang.Long basic.TestGetDeclaredField.size

在Java的反射中Field类和Method类的说明:要想使用反射,首先需要获得类对象所对应的Class类的类对象。一个Field对象对应的是一个反射类的属性(成员变量)信息。Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值。Method类使得我们可以获得方法声明的完整信息。

基于以上信息分析代码如下:

  1. Class cache = Integer.class.getDeclaredClasses()[0];
    Field myCache = cache.getDeclaredField("cache");

获取到内部类和内部类中成员变量名为cache的属性信息。

  1. java.lang.Integer$IntegerCache
    static final java.lang.Integer[] java.lang.Integer$IntegerCache.cache

我们来看JDK中关于Integer内部类IntegerCache中属性cache的源码如下:

  1. /**
  2. * Cache to support the object identity semantics of autoboxing for values between
  3. * -128 and 127 (inclusive) as required by JLS.
  4. *
  5. * The cache is initialized on first usage. The size of the cache
  6. * may be controlled by the -XX:AutoBoxCacheMax=<size> option.
  7. * During VM initialization, java.lang.Integer.IntegerCache.high property
  8. * may be set and saved in the private system properties in the
  9. * sun.misc.VM class.
  10. */
  11.  
  12. private static class IntegerCache {
  13. static final int low = -128;
  14. static final int high;
  15. static final Integer cache[];
  16.  
  17. static {
  18. // high value may be configured by property
  19. int h = 127;
  20. String integerCacheHighPropValue =
  21. sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
  22. if (integerCacheHighPropValue != null) {
  23. int i = parseInt(integerCacheHighPropValue);
  24. i = Math.max(i, 127);
  25. // Maximum array size is Integer.MAX_VALUE
  26. h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
  27. }
  28. high = h;
  29.  
  30. cache = new Integer[(high - low) + 1];
  31. int j = low;
  32. for(int k = 0; k < cache.length; k++)
  33. cache[k] = new Integer(j++);
  34. }
  35.  
  36. private IntegerCache() {}
  37. }

JavaInteger对-127到128的整形数据是有缓存的,你这里通过反射缓存中的第133号数据(既整数5)赋值给了第132号数据(既整数4),所以4就会变成5来表示。在使用int数据计算时结果是正常的,但是在打印时由于做了装箱,int数据变成了Integer,这时会采用缓存,所以4就会打印出5来。

1、易百教程:http://www.yiibai.com/html/java/

2、Java机智的让1+1的结果变成3:http://www.tuicool.com/articles/nIzQJjb

3、segmentfault问题地址:https://segmentfault.com/q/1010000005732476

Java中2+2==5解读的更多相关文章

  1. Java中Websocket使用实例解读

    介绍 现在很多网站为了实现即时通讯,所用的技术都是轮询(polling).轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客服端的浏览器 ...

  2. java中jdbc源码解读

    在jdbc中一个重要的接口类就是java.sql.Driver,其中有一个重要的方法:Connection connect(String url, java.util.Propeties info); ...

  3. java中对象的简单解读

    对象=属性(int double之类都是变量的属性)+方法(想要实现内容,所做的一套算法) 属性=变量的所有数据 方法(c语言中叫做函数)=算法 总而言之 对象就是  给他所需要的的数据-->& ...

  4. 全面解读Java中的枚举类型enum的使用

    这篇文章主要介绍了Java中的枚举类型enum的使用,开始之前先讲解了枚举的用处,然后还举了枚举在操作数据库时的实例,需要的朋友可以参考下 关于枚举 大多数地方写的枚举都是给一个枚举然后例子就开始sw ...

  5. Java面试-List中的sort详细解读

    最近看了一些排序相关的文章,因此比较好奇,Java中的排序是如何做的.本片文章介绍的是JDK1.8,List中的sort方法. 先来看看List中的sort是怎么写的: @SuppressWarnin ...

  6. Java中的泛型 (上) - 基本概念和原理

    本节我们主要来介绍泛型的基本概念和原理 后续章节我们会介绍各种容器类,容器类可以说是日常程序开发中天天用到的,没有容器类,难以想象能开发什么真正有用的程序.而容器类是基于泛型的,不理解泛型,我们就难以 ...

  7. Java中Properties类知识的总结

    一.Properties类与配置文件 注意:是一个Map集合,该集合中的键值对都是字符串.该集合通常用于对键值对形式的配置文件进行操作. 配置文件:将软件中可变的部分数据可以定义到一个文件中,方便以后 ...

  8. java中的23中设计模式(转)

    设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  9. [JavaWeb]关于DBUtils中QueryRunner的一些解读.

    前言:[本文属于原创分享文章, 转载请注明出处, 谢谢.]前面已经有文章说了DBUtils的一些特性, 这里再来详细说下QueryRunner的一些内部实现, 写的有错误的地方还恳请大家指出. Que ...

随机推荐

  1. 飞鱼(FlyFish)——便捷的原型在线制作工具

    关于项目原型制作,小菜先前写过一篇文章<FastUI快速界面原型制作工具>,只不过那个是用C#写的原型制作工具,但是感觉用C#写起来比较费力,而且也不太好用,经过高人指点,茅塞顿开,决定重 ...

  2. Ubuntu 16 安装ElasticSearch

    首先安装Java,参见博客:http://www.cnblogs.com/1zhk/p/6056406.html 下载ElasticSearch安装包 curl -L -O https://artif ...

  3. 浅谈linux 下,利用Nginx服务器代理实现ajax跨域请求。

    ajax跨域请求对于前端开发者几乎在任何一个项目中都会用到,众所周知,跨域请求有三种方式: jsonp; XHR2 代理: jsonp: 这种应该是开发中是使用的最多的,最常见的跨域请求方法,其实aj ...

  4. 【转】SQL删除重复数据方法,留着备用

    感谢孙潇楠前辈的总结,地址http://www.cnblogs.com/sunxiaonan/archive/2009/11/24/1609439.html 例如: id           name ...

  5. nodejs+edatagrid读取本地excel表格

     

  6. Android之JSON解析

    做个Android网络编程的同学一定对于JSON解析一点都不陌生,因为现在我们通过手机向服务器请求资源,服务器给我们返回的数据资源一般都是以JSON格式返回,当然还有一些通过XML格式返回,相对JSO ...

  7. DOM扩展-Selectors API(选择符 API)、元素遍历

    DOM扩展 对DOM的两个主要扩展是SelectorsAPI(选择符API)和HTML5 SelectorsAPI(选择符API)是由W3C发起制定的一个标准,致力于浏览器原生支持CSS查询,Sele ...

  8. iOS开发之使用XMPPFramework实现即时通信(二)

    上篇的博客iOS开发之使用XMPPFramework实现即时通信(一)只是本篇的引子,本篇博客就给之前的微信加上即时通讯的功能,主要是对XMPPFramework的使用.本篇博客中用到了Spark做测 ...

  9. Ubuntu杂记——Ubuntu下Eclipse安装Maven问题

    转:在线安装maven插件问题:Cannot complete the install because one or more required items could not be found. 使 ...

  10. 构建自己的PHP框架--定义ORM的接口

    在上一篇博客中,我们抽象出了Controller的基类,实现了页面的渲染和返回JSON字符串的功能. 那作为一个框架,我们现在还缺少什么?是的,大家应该已经注意到了,我们在这之前从来没有连接过数据库, ...