Object 类中的 clone 方法应该是 shallow 拷贝 那应该是 p1 p2 指向同一个对象 为什么我实际使用的时候却不对?

gzk329 1月前 17

测试类

public class TestCopy {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person("张三", 18, new Address("江苏省", "无锡市"));
        System.out.println(p1);
        //Person{pname='张三', page=18, addr=Address{province='江苏省', city='无锡市'}}

        Person p2 = (Person) p1.clone();
        System.out.println(p1 + " \n" + p2);
        //Person{pname='张三', page=18, addr=Address{province='江苏省', city='无锡市'}}
        //Person{pname='张三', page=18, addr=Address{province='江苏省', city='无锡市'}}

        System.out.println(p1.equals(p2));
        //false

        Address addr2 = new Address("江苏省", "苏州市");
        p2.setAddr(addr2);
        System.out.println("修改地址后===========================================");
        
        System.out.println(p1);
        System.out.println(p2);
        //Person{pname='张三', page=18, addr=Address{province='江苏省', city='无锡市'}}
        //Person{pname='张三', page=18, addr=Address{province='江苏省', city='苏州市'}}
    }
}
源码注释也写的很清楚
Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.
public class Person implements Cloneable{
    private String pname;
    private int page;
    private Address addr;

    public Person() {
    }

    public Person(String pname, int page, Address addr) {
        this.pname = pname;
        this.page = page;
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "Person{" +
                "pname='" + pname + '\'' +
                ", page=" + page +
                ", addr=" + addr +
                '}';
    }

    public void showAll(){
        System.out.println("名字是:" + this.pname + ",年龄是:" + page + ",地址(省+市)是:" + addr.getProvince() + addr.getCity());
    }


    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }


    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public Address getAddr() {
        return addr;
    }

    public void setAddr(Address addr) {
        this.addr = addr;
    }
}

public  class Address{
    private String province;
    private String city;

    public Address() {
    }

    public Address(String province, String city) {
        this.province = province;
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}
最新回复 (5)
  • misaka19000 27天前
    引用 2
    Person 的 equals 是不是被重写了
  • cnxobo 27天前
    引用 3
    浅拷贝的简单理解为创建一个新实例然后属性用 = 一个一个的赋值过去。
    p1 p2 指向的是不同的对象,但是 p1 p2 的引用类型属性指向的对象是一样的。
    也就是 p1.addr 就是 p2.addr 。
    如果你不 p2.setAddr, 直接 p2.getAddr().setCity("苏州市"), 那么 p1 和 p2 的 addr city 都会变成苏州市。
  • beichenhpy 27天前
    引用 4
    直接打印内存地址看看不就完了
  • 楼主 gzk329 27天前
    引用 5
    @cnxobo 明白了 谢谢
  • beichenhpy 27天前
    引用 6
    应该要重写 equals()和 hashCode()吧。。
  • 游客
    7
返回