miracle just wanna be better

值传递和引用传递

2019-07-05
miracle

值传递和引用传递

值传递:(基本数据类型的数据传递,栈中的数据)

基本数据类型的数据作为方法的参数进行传递 ,在方法中会另外开辟一个新的内存空间,跟原来的内存空间不是一个内存空间

  • 如果在方法中对参数的值进行更改,不会影响原来的内存空间的值
  • 如果非要获取方法中修改后的值,则要把修改后的值返回出来

    引用传递:(数组的传递,对象的传递,堆中的数据)

    如果传递的是对象或数组,实际上是把对象或数组的引用传递到方法中,如果在方法中对引用的对象或数组做任何修改,都会影响原来的内存空间的值,即修改了原来内存空间,其实操作的是同一份内存空间

下面例子证明:

值传递

第一次输出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


上一篇 java构造方法

下一篇 java修饰符

Comments

Content