zl程序教程

您现在的位置是:首页 >  后端

当前栏目

对象的引用传递和值传递

对象 引用 传递
2023-09-14 09:07:25 时间

我们在开发的过程中,经常会遇见对象的值传递,和对象的引用传递,老是分不清楚。

今天以下面两个例子,结合内存分析,来讲解值传递和引用传递。

值传递

源代码


/**
 * Created By zby on 20:46 2022/7/27
 * 学生类
 */
public class Student{

    private String name;
    
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void changeStudentName(Student s) {
        s = new Student();
        s.setName("nihao");
    }

    public static void main(String[] args) {
   1     Student student = new Student();
   2     student.setName("珠宝呀");
        
   3    *System.out.println(student.getName());*
        
   4     student.changeStudentName(student);

   5    *System.out.println(student.getName());*
	}
}
output:
		珠宝呀
		珠宝呀

输出结果:

在这里插入图片描述

你会发现,即便我调用了changeStudentName方法,其输出结果也是一样的,为什么会这样呢?

语句1

我们来画一个类加载的JVM结构图,当我们执行语句1时,首先会在栈里分配一个地址空间存储指向student对象1的引用的首地址:

这里写图片描述

语句2

当我们执行语句2的时候,在栈里面分配一个临时变量name,临时变量存储是常量池当中的“珠宝”的地址,而通过set方法中的this.name=name,此时对象的属性存储的临时变量的副本地址,通过这个方法可得:

String p="珠宝呀";
student.setName(p);
student.setName("珠宝");
System.out.println("student-->"+student.getName());
System.out.println("p-->"+p);

output:
	student-->珠宝
	p-->珠宝呀

发现p的值并不没改变,而对象name重新获取新的副本。这个是按值传递。

这里写图片描述

语句4

当方法执行语句4时:此时获取了student对象的副本,副本指向了新的Student对象,并且set了新的名字,而Student初值并没有改变,因而,输出的结果是没有改变。

引用传递

如果将StudentName的返回对象改变了,就会出现不同的结果:

 public Student changeStudentName(Student s) {
        s = new Student();
        s.setName("nihao");

       return s;
    }

    public static void main(String[] args) {

        Student student = new Student();
        System.out.println(student.getName());

        String p="珠宝呀";
        student.setName(p);
        student.setName("珠宝");
        System.out.println("student-->"+student.getName());
        System.out.println("p-->"+p);

        student = student.changeStudentName(student);

        System.out.println("student-->"+student.getName());
    }

	output:
		student-->珠宝
		p-->珠宝呀
		student-->nihao

输出结果:

在这里插入图片描述

因为,通过调用 student.changeStudentName(student);这个方法,返回的是一个新的对象的引用,而student重新指向了新的引用对象,故而,值就被改变了。这个是按引用传递数据。

总结

通过以上两段代码的分析,应该对值传递和引用传递,有个大致的了解了。