参数传递
Java 的参数是以值传递的形式传入方法中,而不是引用传递,下文做详细介绍:
值传递
定义:在调用函数时,将实际参数的副本传递到函数中,这样在函数中对参数进行修改,原来的参数不会受到影响。
1、基本数据类型及其包装类型
示例
基本数据类型:
package com.java.basic;
public class ValuePass {
public static void intPass(int value){
value = 19;
System.out.println("value:"+value);
}
public static void main(String[] args) {
int valueOld = 10;
ValuePass.intPass(valueOld);
System.out.println("oldValue:"+valueOld);
}
}
输出如下:
value:19
oldValue:10
包装类型:
package com.java.basic;
public class ValuePass {
public static void IntegerPass(Integer value){
value = 19;
System.out.println("value:"+value);
}
public static void main(String[] args) {
Integer valueOld = 3;
ValuePass.IntegerPass(valueOld);
System.out.println("oldValue:"+valueOld);
}
}
输出如下:
value:19
oldValue:3
如以上两个例子可以看出,Java中的基本数据类型及其对应的包装类型作为参数时都是pass by value即值传递。
2、String
对于String类型,先看如下的例子:
package com.java.basic;
public class ValuePass {
public static void StringPass(String value){
System.out.println("value地址: "+System.identityHashCode(value));
value = "new string";
System.out.println("value: "+value);
System.out.println("改变指针引用后的value地址: "+System.identityHashCode(value));
}
public static void main(String[] args) {
String oldValue = new String("old String");
System.out.println("oldValue地址: "+System.identityHashCode(oldValue));
ValuePass.StringPass(oldValue);
System.out.println("oldValue: "+oldValue);
}
}
输出如下:
oldValue地址: 1324119927
value地址: 1324119927
value: new string
改变指针引用后的value地址: 1828972342
oldValue: old String
对于String类型的参数,"String value"的value是一个指针,存储的是对象的地址。在将一个参数传入一个方法时,本质上是将对象的地址以值的方式传递到形参中。因此在方法中改变指针引用的对象,那么这两个指针此时指向的是完全不同的对象(从输出中可以看出对象的内存地址发生了改变),一方改变其所指向对象的内容对另一方没有影响。这就是为什么在 "StringPass"函数中使用 value = "new string"改变指针指向后oldValue的值并未发生改变的原因,示例图如下:
3、对象
参数为对象时其实就和String类似,示例如下:
package com.java.basic;
public class Dog {
String name;
Dog(String name) {
this.name = name;
}
String getName() {
return this.name;
}
void setName(String name) {
this.name = name;
}
}
package com.java.basic;
public class ValuePass {
private static void func(Dog dog) {
System.out.println(System.identityHashCode(dog)); // 990368553
dog = new Dog("B");
System.out.println(System.identityHashCode(dog)); // 1096979270
System.out.println(dog.getName()); // B
}
public static void main(String[] args) {
Dog dog = new Dog("A");
System.out.println(System.identityHashCode(dog)); // 990368553
func(dog);
System.out.println(System.identityHashCode(dog)); // 990368553
System.out.println(dog.getName()); // A
}
}
但是如果在方法中改变对象的字段值会改变原对象该字段值,因为改变的是同一个地址指向的内容。
package com.java.basic;
public class ValuePass {
private static void func(Dog dog) {
dog.setName("B");
}
public static void main(String[] args) {
Dog dog = new Dog("A");
func(dog);
System.out.println(dog.getName()); // B
}
}
引用传递
定义:是指在调用函数时将实际参数的地址直接传递到函数中,而传递过来的地址还是与之前的地址指向同一个值,对参数的修改会影响值的改变。
由于Java的参数都是以值传递的形式传入方法中,故不在对引用传递赘述。