值传递和引用传递
值传递:(基本数据类型的数据传递,栈中的数据)
基本数据类型的数据作为方法的参数进行传递 ,在方法中会另外开辟一个新的内存空间,跟原来的内存空间不是一个内存空间
- 如果在方法中对参数的值进行更改,不会影响原来的内存空间的值
- 如果非要获取方法中修改后的值,则要把修改后的值返回出来
引用传递:(数组的传递,对象的传递,堆中的数据)
如果传递的是对象或数组,实际上是把对象或数组的引用传递到方法中,如果在方法中对引用的对象或数组做任何修改,都会影响原来的内存空间的值,即修改了原来内存空间,其实操作的是同一份内存空间
下面例子证明:
值传递
第一次输出a的值是10,调用方法后,方法里的参数a在内存开辟新空间,与a=10互不干扰,因为没有返回值,在方法结束后,在栈区弹出,最后输出的还是main方法里的a=10
第二次输出a的值是100,调用方法后,方法里的参数a在内存开辟新空间,与a=10互不干扰,因为有返回值,在方法结束后,把值赋给main里的a后弹出,所以main方法里的a的值被覆盖,所以a=100
引用传递
Student类被实例化stu,在堆空间开辟新空间,在调用referenceTransfer方法时,参数没有被实例化,所以只开辟了一个内存空间,在方法体中,stu的属性值被覆盖,所以都改变了
public class Demo1 {
/**
* 此方法演示值传递,注意没有返回值
*/
public void valueTransfer(int a){
a=100;
}
/**
* 此方法演示值传递,但注意有返回值
* @param a
* @return
*/
public int valueTransfer1(int a){
a=100;
return a;
}
//引用传递
public void referenceTransfer(Student stu1){
stu1.setAge(stu1.getAge()+1);
stu1.setName("张三");
stu1.setStuNo("s001");
}
public static void main(String[] args) {
Demo1 d1 = new Demo1();
//演示值传递
int a = 10;
d1.valueTransfer(a);
System.out.println(a);
a=d1.valueTransfer1(a);
System.out.println(a);
//演示引用传递
Student stu = new Student();
d1.referenceTransfer(stu);
System.out.println("age="+stu.getAge());
System.out.println("stuNo="+stu.getStuNo());
System.out.println("name="+stu.getName());
}
}
public class Student {
private int age;
private String name;
private String stuNo;
public Student(){
this(18,"无名氏","s003");
System.out.println("无参数构造");
}
public Student(int age, String name, String stuNo) {
this.age = age;
this.name = name;
this.stuNo = stuNo;
System.out.println("有参数构造");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStuNo() {
return stuNo;
}
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public static void main(String[] args) {
}
}
例二
class ClassA {
int value;
}
public class Test {
public static void main(String[] args) {
int value = 10;
changeInt(value);
System.out.println(value);
ClassA ca = new ClassA();
ca.value = 10;
changeObject(ca);
System.out.println(ca.value);
}
public static void changeInt(int value) {
value++;
}
public static void changeObject(ClassA ca) {
ca.value++;
}
}
输出结果是10,11
-
在调用时changeInt(int value),value参数会在内存中开辟新的空间,value++,value的值是10+1=11,但是执行完后,此value值弹出,并未有返回值,所以输出的还是原来的value值10,是两份空间 ,这是一个值传递
-
在调用changeObject时,参数是类类型,ca作为参数传入,ca.value也被传入,此时并未开辟新的空间,ca.value++时,value的值被改为11,改的是堆空间的值,所以输出为11