关于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;
  }
}


输出结果为
```java
Before change, n = 3
After changeData(n), n = 3
```
**由以上例子可以看出,当参数为基本类型时,采用的是值传递的方式**
那么,当参数为对象时又当如何呢?我们再来看一个例子
```java
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!");
}
}
```
输出结果为
```java
Before change, sb = Hello
After changeData(n), sb = Hello World!
```
两次的结果不一样,说明原参数地址中的值发生了改变。足以证明,在上述的例子中传递的是参数的引用。

那么是不是就可以说明对象类型传递的就是引用呢?我们再来看一个例子。
```java
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!");
}
}
```
如果是将参数的引用传递过去了,那么就应该输出以下结果:
```java
Before change, sb = Hello
After changeData(n), sb = Hi World!
```
然后实际的结果却是
```java
Before change, sb = Hello
After changeData(n), sb = Hello
```
上面这个例子原参数的值并没有被改变。是因为**new**关键字的作用。
在使用了new过后,strBuf中存放的不再是指向“Hello”的地址,而是指向“Hi ”的地址了,new操作符操作成功后总会在内存中新开辟一块存储区域。相当于生成了一个新的引用。所以,这和对象类型传递引用并不矛盾。

综上所述:
对于基本数据类型来说 “=”赋值操作是直接改变内存地址(存储单元)上的值。在传递参数时,传递的是值。

对于对象类型来说 “=” 赋值操作是改变引用变量所指向的内存地址。在传递参数时,传递的是地址(引用)。

猜你喜欢

转载自www.cnblogs.com/haruyuki/p/11755770.html