码迷,mamicode.com
首页 > 其他好文 > 详细

从一道题初步了解Integer

时间:2019-06-19 21:39:41      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:click   final   作用   new   onclick   第一个   改变   illegal   show   

  • 题目:两个Integer变量 i=1,j=2,用一个方法swap(Integer i,Integer j)处理之后,交换i、j的值。
  • 习惯逻辑
  • 技术图片
    1 private static void swap1(Integer i, Integer j) {
    2         int tmp = i;
    3         i = j;
    4         j = tmp;
    5     }
    View Code

    调用之后发现,并没有像我们预料的那样起作用,两个值没有交换;

  • 这里说明第一个问题,java调用方法传参数,有两种方式:传值和传引用。如果是传值,本质上传的是值的副本(所以为啥有些时候会需要锁了),而这里就传的值了,所以我们需要改变变量的地址,自然应该用反射
  • private static void swap3(Integer i, Integer j)
                throws NoSuchFieldException, IllegalAccessException {
            Integer tmp = i;
            Field field = Integer.class.getDeclaredField("value");
            field.setAccessible(true);
            field.set(i,j.intValue());
            field.set(j,tmp);
        }

    在Integer中保存值的是

    private final int value;
  •  private的变量正常应该是访问不到的,所以要用field.setAccessible(true);来暴力访问
  • 执行之后发现i的值变成2了,但是j的值还是2;
  • 反向推导一下,j是通过tmp设置的值,tmp的值是通过i获得的,所以可能是i的变化导致了tmp的变化;
  • 读一下Integer的源码有这样一段
  • public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }

    从-128到127之间的值都会被Integer缓存起来,如果在这个范围内,会直接返回缓存的值;

  • 那我们就换一下,i=129,j=130;就会发现刚才那段代码又可以使用了;
  • 说明在这个范围内的值都是获取的同一个,如果想修改刚才的代码,那我们可以直接new一个,这样就可以跳过缓存了;修改一下
    Integer tmp = new Integer(i.intValue());然后就没有问题了。

从一道题初步了解Integer

标签:click   final   作用   new   onclick   第一个   改变   illegal   show   

原文地址:https://www.cnblogs.com/lanhaiyue/p/11055026.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!