从一道题初步了解Integer

Posted lanhaiyue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从一道题初步了解Integer相关的知识,希望对你有一定的参考价值。

  • 题目:两个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的主要内容,如果未能解决你的问题,请参考以下文章

一道面试题了解计算机网络

从一道题学习反弹shell

一道面试题让你更加了解事件队列

一道面试题引发的pythonic

通过一道面试题了解Condition线程通信

主席树初步