您的位置:首页技术文章
文章详情页

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

【字号: 日期:2024-02-11 10:00:41浏览:51作者:猪猪

问题描述

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 stubint[] 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]; }}

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

问题解答

回答1:

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

回答2:

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

回答3:

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

回答4:

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

回答5:

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

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

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

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

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

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

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

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

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

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

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

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

回答6:

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

标签: java
相关文章: