简体   繁体   中英

how Immutable class is created having mutable object as refernce

I am asking very basis question about 'How to make immutable Object in java'.

So I have one Address class from third party which does not inherit any Cloneable interface and its mutable class. It looks like this

public class Address {

    private String city;
    private String address;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Now I have another immutable class called Person which implements Cloneable interface and also override clone method.Class Looks like this

public class Person implements Cloneable {

    private String name;
    private Address address;

    public Person() {

    }

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
        //this.address = (Address) address.clone();
    }

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    @Override
    public String toString() {
        return "name:" + name + ", address" + address.getAddress() + ", city="
                + address.getCity();
    }

}

Now my question is, surely I can clone the Person class object but how can address class instance be cloned. I also read some article about shallow cloning and deep cloning. But I could not understand the how deep cloning can be done with thirty party API. Or correct me if I understood something wrong about cloning.

I think you understand very well: clone is a bad mechanism and there's actually a complete list of things wrong with it (check out Effective Java). Particularly relevant to your case, you cannot deep-clone an object with final fields.

Instead choose a custom mechanism for copying objects, such as copy-constructors or dedicated methods.

There is also a trick with in-memory serialize-deserialize cycle, but I wouldn't really recommend it unless performance and efficiency are not high on your list.

One of the many problems with the Cloneable facility is that after calling super.clone() there can be fields whose state you need to go back and -fix- before returning the cloned value. This prevents you from making those fields final in your class and is at odds with the principle of an immutable class. Moreover, the facility can introduce security vulnerabilities into your class chiefly because it relies on an extralinguistic mechanism for object creation.

A good rule of thumb is if you can avoid implementing Cloneable in your classes, then avoid it.

As Marko mentioned, copy constructors of copy factory methods are usually superior strategies that do not rely upon a flawed, extralinguistic mechanism for object creation. The only good time to use the clone() method of which I am aware is when obtaining defensive copies of arrays of immutable values such as primitives or Strings .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM