关于Java方法的参数传递
我们都知道,函数或者方法在传递参数的时候,大致可以分为两类:
1.传递参数的值。
也就是说在方法内部改变参数时,系统会申请新的内存空间来拷贝参数的值。无论在内部怎么进行赋值操作,改变的都只是这个拷贝的参数的值。而原来的参数并不会发生改变。
2.传递参数的地址(引用)
这种方式,会直接将参数的引用传递给方法。方法则可以根据这个引用直接访问到原参数的地址。在方法内部进行赋值操作时,原参数的值也会随之改变。
那么在Java中,方法参数的传递时哪一种呢?
public class Test1 { public static void main(String[] args) { int n = 3; System.out.println("Before change, n = " + n); changeData(n); System.out.println("After changeData(n), n = " + n); } public static void changeData(int nn) { n = 10; } }
输出结果为
Before change, n = 3
After changeData(n), n = 3
由以上例子可以看出,当参数为基本类型时,采用的是值传递的方式
那么,当参数为对象时又当如何呢?我们再来看一个例子
public class Test2 { public static void main(String[] args) { StringBuffer sb = new StringBuffer("Hello "); System.out.println("Before change, sb = " + sb); changeData(sb); System.out.println("After changeData(n), sb = " + sb); } public static void changeData(StringBuffer strBuf) { strBuf.append("World!"); } }
输出结果为
Before change, sb = Hello
After changeData(n), sb = Hello World!
两次的结果不一样,说明原参数地址中的值发生了改变。足以证明,在上述的例子中传递的是参数的引用。
那么是不是就可以说明对象类型传递的就是引用呢?我们再来看一个例子。
public class Test3 { public static void main(String[] args) { StringBuffer sb = new StringBuffer("Hello "); System.out.println("Before change, sb = " + sb); changeData(sb); System.out.println("After changeData(n), sb = " + sb); } public static void changeData(StringBuffer strBuf) { strBuf = new StringBuffer("Hi "); strBuf.append("World!"); } }
如果是将参数的引用传递过去了,那么就应该输出以下结果:
Before change, sb = Hello
After changeData(n), sb = Hi World!
然后实际的结果却是
Before change, sb = Hello
After changeData(n), sb = Hello
上面这个例子原参数的值并没有被改变。是因为**new**关键字的作用。
在使用了new过后,strBuf中存放的不再是指向“Hello”的地址,而是指向“Hi ”的地址了,new操作符操作成功后总会在内存中新开辟一块存储区域。相当于生成了一个新的引用。所以,这和对象类型传递引用并不矛盾。
综上所述:
对于基本数据类型来说 “=”赋值操作是直接改变内存地址(存储单元)上的值。在传递参数时,传递的是值。
对于对象类型来说 “=” 赋值操作是改变引用变量所指向的内存地址。在传递参数时,传递的是地址(引用)。