如何解释Java中的浅拷贝与按值传递?

Zug*_*dud 4 java

根据我对Java的理解,一切都是通过价值传递的.然而,当你开始谈论包含其他对象的对象时,事情会变得有趣,我希望能够更好地沟通,并确保我也完全理解.所以我的观点是,实际上只复制了对象中的基元,而另一方面它包含的任何对象......这些对象的值不会被复制,而只是这些对象的副本.

所以,如果我们与这些成员有一些对象

public class SomeObject {
   private String name;
   private String address;
   private  List<String> friends;

   public SomeObject(String name, String address, List<String> friends) {
      this.name = name;
      this.address = address;
      this.friends = friends;
   }
}
Run Code Online (Sandbox Code Playgroud)

我们这样做了:

List<String> friendsList = new ArrayList<String>();
        friendsList.add("bob");
        friendsList.add("joe");

        SomeObject so1 = new SomeObject("mike", "123 street", friendsList);

        friendsList.add("zoe");
        friendsList.add("rick");
        SomeObject so2 = new SomeObject("david", "300 ave", friendsList);

        System.out.println(so1.getName() + " " + so1.getAddress());
        for (String friend : so1.getFriends()) {
            System.out.println(friend);
        }

        System.out.println(so2.getName() + " " + so2.getAddress());
        for (String friend : so2.getFriends()) {
            System.out.println(friend);
        }
Run Code Online (Sandbox Code Playgroud)

我们的输出是这样的:

mike 123 street
bob
joe
zoe
rick
david 300 ave
bob
joe
zoe
rick
Run Code Online (Sandbox Code Playgroud)

尽管我们已经创建了2个单独的对象,但它们都保留了对原始好友列表的引用.这就是为什么当人们说Java总是按值传递时,我会有点绊倒.

Lin*_*ded 10

引用按值传递,因此复制指向列表的指针,而不是列表本身.


MBy*_*ByD 6

对列表的引用是按值传递的,而不是列表本身,也就是说,您无法friendsList在构造函数中进行SomeObject更改,但您可以更改它指向的内容.

例如,如果构造函数是这样的:

public SomeObject(String name, String address, List<String> friends) {
    this.name = name;
    this.address = address;
    this.friends = friends;
    friends = new ArrayList<String>();
}
Run Code Online (Sandbox Code Playgroud)

尽管您已将新列表分配给,但仍会获得相同的输出friends.