Java副本是同一个地址吗?
在Java中,创建对象时经常会遇到“副本”的概念。副本是指根据已有对象创建一个具有相同属性值的新对象。那么,这个副本是同一个地址吗?本文将对这个问题进行详细讨论,并给出相应的代码示例。
副本的定义
在Java中,创建副本的方式有多种,包括浅拷贝和深拷贝。浅拷贝是将原对象的值复制到一个新对象中,两者共享相同的引用类型属性。而深拷贝是创建一个全新的对象,并将原对象的值复制到新对象中,包括引用类型属性也是全新的。
浅拷贝示例
以下是一个浅拷贝的示例代码:
class Person {
    private String name;
    
    public Person(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
}
public class ShallowCopyExample {
    public static void main(String[] args) {
        Person person1 = new Person("Alice");
        Person person2 = person1;  // 浅拷贝
        
        person2.setName("Bob");
        
        System.out.println(person1.getName());  // 输出 "Bob"
        System.out.println(person2.getName());  // 输出 "Bob"
    }
}
在上面的代码中,我们创建了一个Person类,它具有一个私有成员变量name和一个公有的getName方法。然后我们创建了一个person1对象,并将其值设置为"Alice"。接下来,我们将person1赋值给person2,这是一个浅拷贝操作。最后,我们通过person2修改了name的值为"Bob",并打印了person1和person2的name属性值。结果显示,person1和person2的name属性值都变为了"Bob"。这表明,浅拷贝创建的副本是同一个地址。
深拷贝示例
以下是一个深拷贝的示例代码:
class Address {
    private String city;
    
    public Address(String city) {
        this.city = city;
    }
    
    public String getCity() {
        return city;
    }
}
class Person {
    private String name;
    private Address address;
    
    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }
    
    public String getName() {
        return name;
    }
    
    public Address getAddress() {
        return address;
    }
    
    public void setAddress(Address address) {
        this.address = address;
    }
}
public class DeepCopyExample {
    public static void main(String[] args) {
        Address address1 = new Address("New York");
        Person person1 = new Person("Alice", address1);
        
        Address address2 = new Address(address1.getCity());
        Person person2 = new Person(person1.getName(), address2);  // 深拷贝
        
        person2.getAddress().setCity("London");
        
        System.out.println(person1.getAddress().getCity());  // 输出 "New York"
        System.out.println(person2.getAddress().getCity());  // 输出 "London"
    }
}
在上面的代码中,我们创建了一个Address类和一个Person类。Person类具有一个name属性和一个address属性,address属性是一个引用类型。我们首先创建了一个address1对象,其city属性值为"New York"。然后我们创建了一个person1对象,并将其address属性值设置为address1。接下来,我们使用address1的属性值创建了一个新的address2对象,并将person1的name属性值和address2赋值给person2,这是一个深拷贝操作。最后,我们通过person2的getAddress方法修改了address的city属性值为"London",并打印了person1和person2的address的city属性值。结果显示,person1的address的city属性值为"New York",而person2的address的city属性值为"London"。这表明,深拷贝创建的副本是不同的地址。
结论
根










