关于Java通过反射实现交换两个数的值的解决与存在的一些问题
标签(空格分隔): 未分类
从网上找了很长时间相关的文章,绝大多数都是在参数另外加上一个数组,从
而实现,但我总感觉有点离谱-_-...,我有那时间,直接引入一个中间变量不就完
事了嘛。
哦对,还有创建了一个Swap类。。。。这这这-_-倒是也行,不过对于只是做
算法题来讲真的是有些麻烦了呢。
还有部分大佬用反射实现倒是实现了,不过有个细节不知道是不是没注意到,
接下来我就详细的说一下吧!
"啊咦哟哟"的解决(就是创建类和另加数组)
直接上代码
private static void swap(Integer a,Integer b){
try {
int temp = a;
Field field = a.getClass().getDeclaredField("value");
field.setAccessible(true);
field.setInt(a, b);
field.setInt(b, temp);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
- 原理就是在Integer类中有一个value值,该变量存储了当前Integer对象的值,所以我们的目标就直接转移到:修改两个对象的value值
- 那么我们就可以通过反射来获取目标对象的value值,从而直接将两个目标对象修改(交换值)
这里要强调一点是:当将temp设置成Integer类型的时候,那么当a的值被修改后,temp的值会随之而改变,原因应该是由于:Integer中存在一个-127~128之间数的缓存,当缓存中存在某个值时,那么多个值相同的Integer对象的value都会指向这个缓存值,所以当a变了指向,那么temp = a即temp的指向也会随之改变
但是修改为int后则没有出现,原因我暂时不是很清楚,有几个猜测:
- 可能是因为创建为int后,temp的值指向不与Integer类的a同步,只是将a的value copy给了temp
- int类内部无数值缓存机制
以上是只有两个数进行交换时的情况,基本已经实现,下面来看看在数组中操作会发生什么情况
我们可以看到,虽然两个位置交换成功,但浏览整个数组,发现另外一个value为0的位置也被影响。
在之前,数组和缓存中的关系应该是这样的(如图):
当位置0和位置3发生指向交换时,代码明确告知了指向的方向,于是nums[0]->3,nums[1]->0,但是作为之前与位置0指向相同的位置2在没有被告知的情况下,于是其指向随着位置0一同修改了指向,所以值同时被更改
所以这种交换方法,在数组中不存在重复值时,可以使用。
但当存在相同值时,会对于交换对象值相同的元素也造成影响所以不应该在数组中使用
对于这个问题,我不知道有没有方法解决,期待各位大佬们的答案。