从方法参数传递进来的变量,会被方法修改了原来的值吗?
想必,这是不少人遇到的面试题目.
先来看看下面这段简单的Java程序和它的输出结果.
public class HelloWorld{
public static void main(String []args){
int i = 10;
test1(i);
System.out.println("test1 i=" + i);
StringBuilder str1 = new StringBuilder("hello");
test2(str1);
System.out.println("test2 str1=" + str1.toString());
StringBuilder str2 = new StringBuilder("hello");
System.out.println("test3 str2=" + str2.toString());
}
private static void test1(int i) {
i = i + 100;
}
private static void test2(StringBuilder str) {
str.append("world");
}
private static void test3(StringBuilder str) {
str = new StringBuilder("helloworld");
}
}
//输出结果
test1 i=10
test2 str1=helloworld
test3 str2=hello
实际上Java的方法参数传递的都是一个副本.我们从上面的程序的3个方法来分析.
1. test1方法的参数是一个int类型,对于基础类型,方法参数是原来变量的一个副本拷贝.所以在方法里面对它做的任何修改都不会影响它的原值.
2. 对于对象类型,方法参数传递的是对象引用的副本,实际是一个地址,指向了这个对象.此时的对象并没有被拷贝,而只是对象的引用被拷贝了一个副本作为方法的参数.因此,当方法内部对参数做的修改,都是修改的这个引用指向的地址,也就是对象原本的修改.因此看到执行完test2方法后,str1的值被修改了.
3. test3的参数和test2的参数情况类似,也是一个对象的引用的副本,他们都指向的地址都是StringBuilder对象本身.而在test3方法内部,参数str2被重新赋值了,str2 = new StringBuilder("helloworld").此时此刻,str2引用所指向的地址已经不再是原本的StringBuilder对象了.所以此后在test3方法内,str2被做的任何修改调用,都不会影响test3方法之外的StringBuilder对象的值了.因此,看到的输出结果,test3方法执行结束后,str2的值并没有被修改.