一个变量,作为参数传入一个函数内,这个函数对参数进行处理,原来的变量是否改变。
下面分情况讨论,示例代码自行运行。
变量是基本类型
public class BasicParamTransTest {
/**
* @Author Johann
* @Description //基本类型 Java只有值传递
**/
public static void basicTest(int m,int n){
int tmp = m;
m = n;
n = tmp;
System.out.println("基本类型处理结果:m = "+m+",n = "+n);
}
public static void main(String[] args){
int m = 10;
int n = 20;
System.out.println("方法执行前:m = "+m+",n = "+n);
basicTest(m,n);
System.out.println("方法执行后:m = "+m+",n = "+n);
}
}
结果:
原变量值不受影响。
分析:
方法中传入的参数是基本类型,经过方法对参数处理后,原来的变量值不变。
其实,传入方法内的参数,只是原来变量的一份Copy,即在栈内再次开辟一个空间,用于存储这个传入的参数。在方法内改变参数的值,当然不会影响本体的值。
变量是引用类型
/**
* @Author Johann
**/
public class ObjectParamTransTest {
public static void trans(Obj obj){
int tmp = obj.m;
obj.m = obj.n;
obj.n = tmp;
System.out.println("对象交换方法中:Obj.m = "+obj.m+",Obj.n = "+obj.n);
}
public static void main(String[] args){
Obj obj= new Obj(10,20);
System.out.println("对象交换方法执行前:Obj.m = "+obj.m+",Obj.n = "+obj.n);
trans(obj);
System.out.println("对象交换方法执行后:Obj.m = "+obj.m+",Obj.n = "+obj.n);
}
}
class Obj{
Obj(){}
Obj(int a,int b){
m = a;
n = b;
}
int m;
int n;
}
结果
原变量受影响。
分析
方法中传入的是引用类型,这个引用类型的数据是存储在堆内的,在栈内只是存储的这个对象的引用。所以在方法内传入的参数,其实只是这个引用的Copy,这两个引用指向同一个对象。
当我们在方法内改变这个参数的时候,实际上改变的是堆中的对象,所以原来的栈内引用没有改变,但是这个引用指向的对象,却改变了。
变量是String和包装类
String和包装类,也属于引用类型,但是它和其他的引用类型得到的预期结果不一致,故分开讨论。
public class WrapperParamTransTest {
public static void wrapperTest(Integer m,Integer n){
Integer tmp = m;
m = n;
n = tmp;
System.out.println("包装器类型处理结果:m = "+m+",n = "+n);
}
public static void main(String[] args){
Integer m = 10;
Integer n = 20;
System.out.println("方法执行前:m = "+m+",n = "+n);
wrapperTest(m,n);
System.out.println("方法执行后:m = "+m+",n = "+n);
}
}
public class StringTransTest {
public static void stringTest(String m,String n){
String tmp = m;
m = n;
n = tmp;
System.out.println("String参数处理结果:m = "+m+",n = "+n);
}
public static void main(String[] args){
String m = "i love China";
String n = "hello world";
System.out.println("方法执行前:m = "+m+",n = "+n);
stringTest(m,n);
System.out.println("方法执行后:m = "+m+",n = "+n);
}
}
结果
原变量不受影响。
分析
当对象是 String,或者基本数据类型的包装类时,参数传入方法处理后,原来的变量值不变。这是因为,【String 是不可变的,包装类的值也是不可变的】。
在方法中当参数被修改的时候,是在堆中重新开辟空间,存储新的字符串或包装类对象,并将参数重新指向新开辟空间的地址。参数是什么,原变量的Copy吖,原变量当然不变。