Java参数传递问题
都说Java只有按值传递,也就是说传入方法的参数只是一个副本,方法内对这个数的操作是不会改变原来的值的。
那么为什么我传一个数组到快速排序的方法,方法执行完成之后,输出数组的值发生了变化呢??
private
static
int
[] a = {
8
,
7
,
6
,
3
,
5
,
4
};
public
static
void
main(String[] args) {
System.out.println(
"排序前:"
+Arrays.toString(a));
QuikSorter.quikSort(a,
0
, a.length -
1
);
System.out.println(
"排序后:"
+Arrays.toString(a));
}
输出结果:
排序前:[8, 7, 6, 3, 5, 4]
排序后:[3, 4, 5, 6, 7, 8]
所谓值不仅仅指的是常量值,也指地址值,你传入的a和你输出的a其本身地址值并没有发生改变,所以你只是对原数组本身进行了元素排序,这无关数组自身,就 比如你将数组下标为0的元素改了其他值,再输出,你就说他的值发生了变化,这说法对吗?说白了你这个根本就无关值传递的问题,还有你排序的结果好像有点问 题
哦,你好意思看错了,上面是排序前,结果没错
java不只有值传递,也有引用传递,对于基础数据类型,是值传递,对于引用类型,传递的是对象的引用,数组是引用类型。
java的参数是原值的地址引用传递,不改变引用的地址,改变该地址内部存储的值,这样的话会影响到引用地址的内部变化。
基础数据类型是值传递,比如int、double等,应用类型的就是地址传递,数组属于地址传递
Java只有值传递。用户可以操作的参数传递都是传值,基本数据类型传递的是变量的值,引用数据类型传递的也是变量的值,只不过这个值是对象在堆中的引用地址,与传址的指针有区别。
二者的区别:
第一个区别,指针需要用专门的指针变量存储(这个变量的值为内存地址),Java中没指针变量,而传递的对象引用不是内存地址而是对象的索引规则([email protected]),因此Java不传址只传值;
另外一个区别,C中传址方式传递的值直接可在内存中找到堆中数据,而Java专递的引用值是间接找到堆中的数据。
Q&A有误请指正。
在Java数据的类型中,数组属于引用数据类型,参数列表中的数组是对原数组引用的拷贝,如果把原数组比作房间,这步操作相当于直接直接获得房间的钥匙,自然就可以拿到数组,然后可以对它进行操作。
Java引用地址的值,他不是个地址吗,c指针变量的值也是地址,我还是没怎么明白
Java引用地址的值,他不是个地址吗,c指针变量的值也是地址,我还是没怎么明白
这么说吧,Java传值引用不是纯内存地址,而C的指针的值就是纯内存地址(因此访问更快)。
刚刚做了个实验,写了一个方法,在里面传进去的array=null,但方法体外部的array还能输出正确的结果,我想我差不多知道了
按引用传递不是这个意思吧
首先要理解几个概念,基本类型(不包括字符串类型)值不同地址也不同,赋予操作如果是基本类型的话(不包括字符串类型)就是直接把值的地址传递给变量,其他类型就是把该实例类型的内存地址传递给变量。
你改的是这个引用指向的对象,没有改这个引用。你可以重新new个数组对象赋值给传进来的参数,你再看看会不会变。
不仅仅是java,所有语言都这样,lrc歌词底层原理决定了只能这样。每个方法帧执行完弹出,不可能影响上一个方法帧中的数据,否则就乱套了
java引用封装了指针
实例分配在jvm的堆中,不过你这个数组是静态变量,在jvm的方法区,但也是共享区域,也就是说目前这玩意儿就一个。你只要是浅拷贝,在哪新建变量来赋值,都是指向这一个数组的引用。
对于引用类型,变量存的是指向实例的引用。