浅谈java两个数的异或交换以及反射和Integer的缓存机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈java两个数的异或交换以及反射和Integer的缓存机制相关的知识,希望对你有一定的参考价值。
今天看数据结构的时候看到一个通过异或(位运算)交换数组内的数的方法。
import java.lang.reflect.Field;
public class test
public static void main(String[] args)
int arr[]=1,2,3,4;
System.out.println("1:"+arr[0]+"|2:"+arr[3]);
swap(arr, 0, 3);
System.out.println("1:"+arr[0]+"|2:"+arr[3]);
public static void swap(int []arr, int i, int j)
//i=2 j=3
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
/*
流程分析如何实现交换
0101 = 0001 ^ 0100 = 6
0001 = 0101 ^ 0100 = 1
0100 = 0101 ^ 0001 = 5
**/
在尝试之后,联想到了java没有指针,java做不到真正的引用传递(对一块内存地址操作,而非对拷贝的地址),便想到用反射交换两个数
import java.lang.reflect.Field;
public class test
public static void main(String[] args)
Integer a =2, b=3;
System.out.println("a="+a+" | b="+b);
try
swap2(a, b);
catch (NoSuchFieldException e)
e.printStackTrace();
catch (IllegalAccessException e)
e.printStackTrace();
System.out.println("a="+a+" | b="+b);
public static void swap2(Integer a, Integer b) throws NoSuchFieldException, IllegalAccessException
int temp = a;
Field field = a.getClass().getDeclaredField("value");
field.setAccessible(true);
field.setInt(a, b);
field.setInt(b, temp);
运行截图
而如果将int temp = a;改为Integer temp = a;呢
结果如下
这是什么原因呢?
这就涉及到了java中Integer 的缓存机制
Integer的缓存机制: Integer是对小数据(-128~127)是有缓存的,再jvm初始化的时候,数据-128~127之间的数字便被缓存到了本地内存中,如果初始化-128~127之间的数字,会直接从内存中取出,不需要新建一个对象.
我们添加一个变量debug一下
下一步
wow,很有意思,temp的值’貌似‘也随着a的变化而变化了,但事实是这样吗?下一行的temp2怎么也变化了?它只是做了一个简单的赋值,它怎么也变了?
个人理解:当缓存中存在某个值a时,如果存在多个Integer对象的值都等于(或指向)这个缓存值a,那么当a改变了值的时候,原本等于(指向)a的Integer对象的值也会随着改变,由于Integer是对小数据(-128~127)是有缓存的,上述代码a和temp2都等于2 符合条件,因此temp2也会随着改变
那么当我们把a和temp的值改为128时
下一步
如我们所料,这次temp2的值并没有改变。
那好,我们回到开始,如何用Integer定义的变量实现交换而不是随着a的变化而变化呢?
改成下面这样就可以了
Integer temp = new Integer(a.intValue());
那为什么这次的temp不会随着a的值变化而变化呢?这就留到下次再写吧(2021.12.19) (~ ̄▽ ̄)~
以上是关于浅谈java两个数的异或交换以及反射和Integer的缓存机制的主要内容,如果未能解决你的问题,请参考以下文章