概念
在Java编程语言中,所有的参数传递都是通过值传递的方式进行的,这意味着不管是一个原始数据类型的变量还是一个对象的引用,传递的都是变量的一个副本。
原始数据类型(值传递)
对于原始数据类型(如int、float、char等),因为它们本身就是值,所以当将它们作为参数传递给方法时,传递的是这些值的一个副本。在方法内部对这个值的任何操作都不会影响到原始的变量。
public class Main {
public static void main(String[] args) {
int a = 10;
System.out.println("Before change: " + a);
changeValue(a);
System.out.println("After change: " + a);
}
public static void changeValue(int num) {
num = 20;
}
}
输出将会是:
Before change: 10
After change: 10
即使changeValue方法改变了它的参数num,原始变量a的值并没有改变,因为传递的是a的副本。
对象引用(也是值传递)
对于对象引用,传递的也是引用的副本,而不是对象本身。这个引用指向堆内存中的对象。如果在方法内部改变了引用指向的对象,那么原始引用指向的对象也会被改变。但是,如果在方法内部改变了引用本身,使其指向一个新的对象,那么原始引用并不会改变。
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
System.out.println("Before change: " + sb);
changeReference(sb);
System.out.println("After change: " + sb);
}
public static void changeReference(StringBuilder str) {
str.append(" World");
}
}
输出将会是:
Before change: Hello
After change: Hello World
在这个例子中,changeReference方法改变了StringBuilder对象的内容,因为传递的是引用的副本,而这个副本和原始引用指向同一个对象。
改变引用本身
如果在方法内部改变了引用本身,使其指向一个新的对象,那么原始引用并不会改变。
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
System.out.println("Before change: " + sb);
changeToNewReference(sb);
System.out.println("After change: " + sb);
}
public static void changeToNewReference(StringBuilder str) {
str = new StringBuilder("Hello New");
}
}
输出将会是:
Before change: Hello
After change: Hello
在这个例子中,虽然在changeToNewReference方法内部str指向了一个新的StringBuilder对象,但是原始引用sb并没有改变,它仍然指向最初创建的对象。
总结来说,Java中的参数传递总是值传递,但是对于对象引用来说,传递的是引用的值,这个引用指向堆内存中的对象。因此,可以在方法内部改变对象的状态,但是不能改变原始引用本身。