Heim > Fragen und Antworten > Hauptteil
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];
}
}
这样子我试了一下,就可以达到交换的目的了
好困惑啊,求解!!
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,看看结果。
PHP中文网2017-04-18 10:49:30
swapEqual函数里面,只是改变了形参a、b的引用,并没有改变实参c、d的引用。
而swap里面,改变的c、d对应的区域的值了。
补充一下,Java里面数组也是对象,所以a、b、c、d都是引用。
阿神2017-04-18 10:49:30
Java的引用(包括基本类型,对象引用类型)在声明、方法调用等时候都会产生新的引用,复制等号右侧的引用。分为下面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出来的对象占多大内存并不能确定,只能在运行期间才能分配,才能明白这个对象分配多大。 而且占用内存不能确定的原因还有一个就是,方法在执行的时候才分配内存。如果没有调用方法,那方法只是一堆代码而已,并不占用内存。