Object is cloned , but static references still exists?

I was learning about object deep cloning , I have an employee class with a getInstance method which returns a singleton and I am cloning the returned object.Below is the class and test class.

public class Employee  implements Serializable , Cloneable {

    public static Employee employee;

    private String name;

    private int age;


    private Employee(){


    }


    public Employee(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    protected Object clone() throws CloneNotSupportedException {

        return super.clone();

        }


    public static Employee getInstance(){

        if(employee == null ){
            employee = new Employee();
            return employee;
        }


        return employee;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public int getAge() {
        return age;
    }


    public void setAge(int age) {
        this.age = age;
    }



}

Object deep copy test class

public class CopyTest {

    /**
     * @param args
     */
    public static void main(String[] args) {



        try {

            Employee original = Employee.getInstance();

            original.setName("John");
            original.setAge(25);

            Employee cloned = (Employee)copy(original);

            System.out.println("Original -->"+Employee.getInstance().getName());

            cloned.getInstance().setName("Mark");

            System.out.println("Cloned -->"+cloned.getInstance().getName());

            System.out.println("Original -->"+Employee.getInstance().getName());

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    public static Object copy(Object orig) {
        Object obj = null;
        try {
            // Write the object out to a byte array
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(bos);
            out.writeObject(orig);
            out.flush();
            out.close();

            // Make an input stream from the byte array and read
            // a copy of the object back in.
            ObjectInputStream in = new ObjectInputStream(
                new ByteArrayInputStream(bos.toByteArray()));
            obj = in.readObject();
        }
        catch(IOException e) {
            e.printStackTrace();
        }
        catch(ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
        }
        return obj;
    }
}

Output

Original -->John
Cloned -->Mark
Original -->Mark

Problem

Eventhough I clone the original object to create a copy of it ,

Employee cloned = (Employee)copy(original);

And I modify the cloned object's property by calling

cloned.getInstance().setName("Mark");

It is reflecting to the original object as you can see from the console output. I assume this is because of the static call ? , and how do I overcome this ? Am I violating the principle that I need a single instance of the object by getInstance method and then I decided to make a copy of the object later on.


This what the JAVA Doc tutorial page says:

Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.

The cloned object cloned is just another object of the class. It is not changing another object to which it doesn't have a reference. your call cloned.getInstance() is returning the static object employee to which all the object can access, because static object associate with Class , not to any specific object. So you call to cloned.getInstance().setName("Mark"); is just equivalent to Employee.employee.setName("Mark");


You are setting the name on Employee instance of the static field employee

cloned.getInstance().setName("Mark");
      ^ static method call that returns the employee reference

and printing it too

System.out.println("Cloned -->"+cloned.getInstance().getName());
                                      ^ static method call

You might want to actually change the cloned instance

cloned.setName("Mark");
System.out.println("Cloned -->"+cloned.getName());

A static field roughly means that it will be shared by every object. Regardless how many objects you have created/cloned, your getInstance() call will return the same Employee.

Therefor, as soon as you set its name as Mark, you will always get Mark in the console.

For example:

Employee me = new Employee();
Employee.getInstance().setName("Mark");
System.out.println("me employee name? " + me.getInstance().getName());

Don´t be surprised if you get "Mark" in the console ;)

For a more detailed information about the difference between instance and class (using the static keyword) members, have a look to this tutorial section

链接地址: http://www.djcxy.com/p/6972.html

上一篇: 具有矩阵(Java)的对象的深拷贝(克隆)

下一篇: 对象被克隆,但静态引用仍然存在?