Java方法参数传递机制
值传递:值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。
引用传递:引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。
1.参数的值传递:
public static void change(int i, int j) {
inttemp = i;
i =j;
j =temp;
}
public static void main(String[] args) {
inta = 3;
intb = 4;
change(a,b);
System.out.println(a);
System.out.println(b);
}
//输出为:
3
4
值传递是指方法调用时,实际参数把它的值传递给对应方法的形参,如change()方法中i和j,也在内存空间中分配了存储单元,这样形参在change()方法中的改变不会影响实际参数的值。
值传递的数据类型包括,八种基本数据类型和String。
2.引用传递
值传递的数据类型包括,八种基本数据类型和String,八种数据类型还比较好理解,比如上面中的int,但是String并不是基本数据类型,这要怎么理解呢。比如下面这个例子。
public class Example {
String str = new String("abc");
char[] ch = { 'a', 'b', 'c' };
public static void main(String args[]) {
Example ex = new Example();
ex.change(ex.str, ex.ch);
System.out.println(ex.str);
System.out.println(ex.ch);
}
public void change(String str, char ch[]) {
//ch = new char[]{'a','b','c'};
str = "change";
ch[0] = 'c';
}
}
//这个例子的输出为:
abc
cbc
要知道String和char数组都是引用类型,不是基本类型。
当我们把str作为参数传入方法后,会新建另一个变量,已经不是原来的变量了,但是他们指向的数据区域都一样,所以如果你在方法中改变了str指向的数据区域,即执行str = "change",那也只是改变新建的另一个变量所指向的数据区域,即指向一个新对象"change",str仍然指向原来的数据区域。所以会输出abc。
但是对于char数组的例子呢,即对象类型,也就是Object的子类(除了String),是把ch的引用传递进来,即引用传递。这样里面和外面的ch都指向了相同的数据区域,执行ch[0] = 'c',就会把这个数据区域里的第一个字符改成c,并没有改变内部ch的数据地址,所以这个修改也会反映到外部的ch。所以会输出cbc。如果你改变了内部ch所指向的数据区域,即把上面代码中注释的那一行打开,即执行ch = new char[]{'a','b','c'},这样ch已经指向一个新的数据区域。输出的结果肯定也就是abc了。
3.两种数据传递总结
值传递和引用传递的本质区别在于是否在传递的时候进行对象的内存拷贝。
基本类型是由于在JVM中存储区域不同于普通对象所以传递前会拷贝,传递的是拷贝后的值,但是对象在传递的时候不拷贝,直接传“引用值”,指向同一片对象堆内存区域,当然要注意String这种特殊情况。