浅谈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的缓存机制的主要内容,如果未能解决你的问题,请参考以下文章

指针的异或运算可用于交换两个变量的值

java 交换两个数的值(临时变量,加减,异或)

如何不用第三个变量实现两个数的交换

如何不利用一个额外的变量来达到交换两个变量值的目的-------位上的异或运算

Chris and Road

异或运算实现两个数的交换