关于Java引用传递的一个困惑?
ringa_lee
ringa_lee 2017-04-18 10:47:30
0
6
521
    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_lee
ringa_lee

ringa_lee

Antworte allen(6)
PHPzhong

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,看看结果。

Ty80

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

伊谢尔伦

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

Peter_Zhu

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

阿神

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出来的对象占多大内存并不能确定,只能在运行期间才能分配,才能明白这个对象分配多大。 而且占用内存不能确定的原因还有一个就是,方法在执行的时候才分配内存。如果没有调用方法,那方法只是一堆代码而已,并不占用内存。

伊谢尔伦

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

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!