Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。
如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
如果参数类型是引用类型,那么传过来的就是这个引用参数的副本(地址值,本质上是按值传递),这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,如设置对象属性的值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会 改变参数 的值。
传递值的数据类型:八种基本数据类型和String(这样理解可以,但是事实上String也是传递的地址,只是string对象和其他对 象是不同的,
string对象是不能被改变的,内容改变就会产生新对象
。那么StringBuffer就可以了,但只是改变其内容。不能改变外部变量所指 向的内存地址)。
传递地址值的数据类型:除String以外的所有复合数据类型,包括数组、类和接口
class A {
int i = 0 ;
}
public class Test {
public static void add(A a) {
a = new A();
a.i++;
}
public static void main(String args[]) {
A a = new A();
add(a);
System.out.println(a.i);
}
}
- 输出结果是 0
- 在该程序中,对象的引用指向的是A ,而在change方法中,传递的引用的一份副本a则指向了一个新的OBJECT,并对其进行操作。
- 而原来的A对象并没有发生任何变化。 引用指向的是还是原来的A对象。
public class Example {
String str = new String( "good" );
char [] ch = { 'a' , 'b' , 'c' };
public static void main(String args[]) {
Example ex = new Example();
ex.change(ex.str, ex.ch);
System.out.print(ex.str + " and " );
System.out.println(ex.ch);
}
public void change(String str, char ch[]) {
str = "test ok" ;
ch[ 0 ] = 'g' ;
}
}
- 程序 3 输出的是 good and gbc.
- String 比较特别,看过String 代码的都知道, String 是 final 的。所以值是不变的。 函数中String对象引用的副本指向了另外一个新String对象,而数组对象引用的副本没有改变