为啥对对象的第二次引用不会改变 java 中的内容?

Posted

技术标签:

【中文标题】为啥对对象的第二次引用不会改变 java 中的内容?【英文标题】:why a second reference to an object does not alter the content in java?为什么对对象的第二次引用不会改变 java 中的内容? 【发布时间】:2022-01-16 05:53:27 【问题描述】:

在下面的代码中,我创建了 Movie 类的 3 个实例。我已经为这三个对象分配了一些数据。其次,我创建了对对象movie1(movie4) 的第二个引用。我还为movie4的属性赋值。 我打印了电影 1 的新属性但内容没有改变。为什么会这样?确切的原因是什么?我知道更新内容的其他方法,但我想知道为什么第二次引用不起作用。 内容是movie1还是一样的。为什么?

class Driver

    public static void main(String[] args)
        
        Movie movie1 = new Movie("The Shawshank Redemption", 1994, 9.3);
        Movie movie2 = new Movie("The Godfather", 1972, 9.2);
        Movie movie3 = new Movie("The Dark Knight", 2008, 9.0);

        **Movie movie4 = movie1;
        movie4 = new Movie("The Return of the King", 2003, 8.9);**

        movie4.name = "The Return of the King";
        movie4.year_of_release = 2003;
        movie4.rating = 8.9;
        System.out.println("\n*********New Movie 1 Details*************\n");
        movie1.printDetails();

    

【问题讨论】:

因为movie4 不再指向movie1。您没有修改 movie4 指向的对象,只是 what movie4 指向的对象。 你能再解释一下吗? movie1movie4 视为标签。您刚刚将movie4 标签移动到另一个对象。这不应该改变 movie1 仍然坚持的内容。 理解变量不是对象对于 Java 编程来说至关重要,它是一个一次只能引用一个对象(或持有一个原始值,但那在旁边)这里的重点)。 【参考方案1】:

这使得movie4 指向movie1

Movie movie4 = movie1;

但是,那么您立即更新了movie4 以指向一个不同的 对象:

movie4 = new Movie("The Return of the King", 2003, 8.9);

因此,此时movie1movie4 不再指向同一个Movie,因此您通过movie4 所做的更改不会影响movie1 指向的对象。

如果您更改对象而不替换movie4

Movie movie4 = movie1;
movie4.name = "The Return of the King";

...那么无论您查看movie1.name 还是movie4.name,您都会看到对象的变化。

更多细节:

在你这样做之后:

Movie movie1 = new Movie("The Shawshank Redemption", 1994, 9.3);
Movie movie2 = new Movie("The Godfather", 1972, 9.2);
Movie movie3 = new Movie("The Dark Knight", 2008, 9.0);

...你的记忆中有这样的东西(省略了很多细节):

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影1:Ref4516−−−−−−−>| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:“肖申克……” | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影2:Ref8469−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《教父》| | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影3:Ref4789−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《黑暗骑士》 | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

然后你这样做了:

Movie movie4 = movie1;

...使movie4movie1 指向同一部​​电影:

电影1:Ref4516−−−+ | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−>| (电影) | | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影4:Ref4516−−−+ |名称:“肖申克……” | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影2:Ref8469−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《教父》| | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影3:Ref4789−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《黑暗骑士》 | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

到目前为止,一切都很好,但后来你做到了:

movie4 = new Movie("The Return of the King", /*...*/);

...这使得movie4 指向一个新对象:

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影1:Ref4516−−−−−−−>| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:“肖申克……” | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影2:Ref8469−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《教父》| | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影3:Ref4789−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《黑暗骑士》 | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ movie4:Ref9546−−−−−−−>| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:“...的回归” | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

因此,分配给 movie4.name 只会更改新对象,而不是 movie1 指向的对象。

如果您没有这样做movie4 = new Movie(/*...*/) 位,那么movie1movie4 仍然指向同一个对象

电影1:Ref4516−−−+ | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−>| (电影) | | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影4:Ref4516−−−+ |名称:“肖申克……” | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影2:Ref8469−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《教父》| | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影3:Ref4789−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《黑暗骑士》 | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

...然后分配给movie4.name 将更改movie4movie1 都指向的对象:

movie4.name = "The Return of the King";
电影1:Ref4516−−−+ | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−>| (电影) | | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影4:Ref4516−−−+ |名称:“...的回归” | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影2:Ref8469−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《教父》| | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 电影3:Ref4789−−−−−−−->| (电影) | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |名称:《黑暗骑士》 | | ... | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

【讨论】:

【参考方案2】:

执行此命令后

Movie movie4 = movie1;

movie4 的值是对movie1 的引用,所以此时对movie4 所做的更改将反映在movie1 中。

movie4 = new Movie("The Return of the King", 2003, 8.9);

但是在这个命令之后,movie4 不再持有对movie1 的引用,它的值是一个全新的引用。因此,所做的任何更改都只会在movie4 指向的新对象上进行,而不是在movie1 上进行

【讨论】:

以上是关于为啥对对象的第二次引用不会改变 java 中的内容?的主要内容,如果未能解决你的问题,请参考以下文章

小结111

《JAVA 技术》第二次作业

第二次Java实验报告

通过引用传递;为啥原始对象没有改变?

java总结第二次(剩余内容)//类和对象1

Java四种引用类型