从一道题初步了解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
调用之后发现,并没有像我们预料的那样起作用,两个值没有交换;
- 这里说明第一个问题,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的主要内容,如果未能解决你的问题,请参考以下文章