suchen

Heim  >  Fragen und Antworten  >  Hauptteil

关于Java引用传递的一个困惑?

    public static void swapEqual(int[] a,int[] b){
        int[] temp=new int[b.length];
        temp=b;
        b=a;
        a=temp;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] c={1,2};
        int[] d={3,4};
        swapEqual(c,d);
        System.out.println(c[1]);
    }

为什么打印出来的C[1]还是原来的2啊,为什么没有交换。数组的=不就是复制引用吗?通过函数可以把a,b的引用交换,这样不就是把内容交换了吗?
干嘛非要这样写?
public static void swap(int[] a,int[] b){
    int[] temp=new int[b.length];
    for(int i=0;i<b.length;i++){
        temp[i]=b[i];
    }
    for(int i=0;i<b.length;i++){
        b[i]=a[i];
    }
    for(int i=0;i<b.length;i++){
        a[i]=temp[i];
    }
}

这样子我试了一下,就可以达到交换的目的了
好困惑啊,求解!!

ringa_leeringa_lee2804 Tage vor559

Antworte allen(6)Ich werde antworten

  • PHPz

    PHPz2017-04-18 10:49:30

    swapEqual(int[] a,int[] b)中:
    一开始:
    a --> {1,2}(地址1)
    b --> {3,4}(地址2)
    经过你的代码处理(a,b指向的地址交换了):
    b --> {1,2}(地址1)
    a --> {3,4}(地址2)
    但是不会对c,d造成影响,c,d依旧是:
    c --> {1,2}(地址1)
    d --> {3,4}(地址2)

    //=================================

    swap(int[] a,int[] b)中:
    一开始:
    a --> {1,2}(地址1)
    b --> {3,4}(地址2)
    经过你的代码处理(地址1,2中的值交换了):
    a --> {3,4}(地址1)
    b --> {1,2}(地址2)
    虽然不会对c,d指向的地址造成影响,但是原本地址下的值已经改变了:
    c --> {3,4}(地址1)
    d --> {1,2}(地址2)

    //=======================================

    我的理解是这样,写完发现与@lianera的表述是同一个意思,就当是补充说明了。

    //=======================================

    你可以尝试用return把swapEqual(int[] a,int[] b)中交换后的a,b的值赋给c,d,看看结果。

    Antwort
    0
  • PHP中文网

    PHP中文网2017-04-18 10:49:30

    swapEqual函数里面,只是改变了形参a、b的引用,并没有改变实参c、d的引用。
    而swap里面,改变的c、d对应的区域的值了。
    补充一下,Java里面数组也是对象,所以a、b、c、d都是引用。

    Antwort
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:49:30

    Java 里的引用和 C++ 里的引用概念有点不一样,Java 里的引用相当于 C++ 中的指针,所以你直接对形参赋值是改变不了实参的。

    Antwort
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:49:30

    看看这个回答。https://www.zhihu.com/questio...

    Antwort
    0
  • 阿神

    阿神2017-04-18 10:49:30

    Java的引用(包括基本类型,对象引用类型)在声明、方法调用等时候都会产生新的引用,复制等号右侧的引用。分为下面3种情况:

    1. 基本类型代表的值存储在引用里面,引用中专门有个区域存储这个值,所以在复制的时候,值也同时被复制了。

    2. 引用类型这个区域存储的是对象在堆内存中的内存地址,引用复制的时候,指向的内存地址却是同一份,所以不会涉及值(也就是对象)的复制

    3. 数组里面都是存储的引用(包括基本类型,对象引用类型)


    引用信息:在Java中,引用数据类型占内存吗?

    要弄清楚这个问题,首先要清楚,在JAVA中有四类八种基本类型,除了基本类型,全都是引用类型。比如你写 int i = 1; 那么它在内存里的分配是这样的:内存里分配了一块空间,这块空间的名字是i,里面的内容是1.

    当你使用i的时候就可以访问这块空间里的内容。而引用类型不同,引用类型在内存中占两块内存。比如:你写String s;或者String s = null;这时候在内存里分配一块内存。这块内存装的是空值null,也就是什么也没有装。因为还没有进行初始化。上个图:

    至于具体这个s分配在哪,要看他被声明的位置。如果s被声明为局部变量,那s就在栈空间。如果不是局部变量,那就不在栈上分配。而当你用s指向一个String类型的对象的时候,就发生了变化。也就是接着写s = new String("zhihu");的时候。上个图:

    原来的s里面就会有一个值,根据s这块空间里的这个值就可以找到在堆上找到另一块内存。所有new出来的东西都在堆内存里。堆上的这块内存里对String的属性进行分配。堆内存是动态分配内存的。所以既然是分配在堆上,其实也就说明了new出来的对象占多大内存并不能确定,只能在运行期间才能分配,才能明白这个对象分配多大。 而且占用内存不能确定的原因还有一个就是,方法在执行的时候才分配内存。如果没有调用方法,那方法只是一堆代码而已,并不占用内存。

    Antwort
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:49:30

    谢谢大家的回答,都讲的挺好的。我也明白了

    Antwort
    0
  • StornierenAntwort