java中的值传递

Java中只有值传递,没有引用传递。

Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。 如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值. 如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数(改变原来的值)。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。

1.当传递的是基本数据类型时,对基本数据类型的修改不会改变原始数据。

2.当传递的是数组时,实际上传递的是数组的地址,数组的内容存在堆内存中。调用方法中修改了数组的内容时,原数组的内容也要改变的,因为调用方法修改了堆内存中数组的内容,而原始数组也是指向该地址的,引用没有改变,但是堆中值变了,所以原数组内容也就变了。。。对于这种问题最好画图分析,尤其是牵扯到引用也发生变化。

如上代码,在调用方法中修改了数组的内容,原始数组内容也会发生变化。

 

 

3:对于字符串而言,也是跟数组差不多,这里传递的是引用的一个副本。画内存图分析就好理解了。这里要注意String和StringBuilder的区别。下面以StringBuilder为例。

public class Test {
public static void main(String[] args) {
    StringBuffer a = new StringBuffer("A"); 
    StringBuffer b = new StringBuffer("B"); 
    operator(a, b); 
    System.out.println(a + "," + b); 
public static void operator(StringBuffer x, StringBuffer y) { 
    x.append(y); y = x; 
}
}
该代码的输出是AB,B....画内存图分析(牛客网上菜鸟葫芦娃的解析https://www.nowcoder.com/profile/7795492/myFollowings/detail/4420831)
此时栈和堆内存中的状态如下图所示:
 
 
publicstaticvoidoperator(StringBuffer x, StringBuffer y) { 
    x.append(y); y = x; 
}
进入如下方法后,内存中的状态为:
 
 
 x.append(y);
这条语句执行后,内存的状态为:因为StringBuilder是可变的,所以是在原字符串上直接添加
 
 
 y = x; 
这条语句执行后,内存的状态为:
 
 
当operator方法执行完毕后内存中的状态为:因为方法执行完毕,局部变量消除。
 
这个题,x是a引用的副本,但是x只是改变了内容,没有改变引用,所以a受影响。y是b引用的副本,y只改变了引用,所以b没有受影响。
 
这里的数据结构如果是String,则a和b都不会发生变化,因为x+"B",这时会重新开辟空间,存放此AB变量,x指向AB,但是a指向不变,因为String是不可变的。

posted on 2017-12-20 21:01  夜的第八章  阅读(166)  评论(0编辑  收藏  举报

导航