如何在java程序中使用clone方法

时间:2014-07-31 08:20:23

标签: java

我想知道它将给该计划带来什么影响?我在网上看过几个例子,但是不知道这个例子是什么?

我只知道这一点: 能够创建与原始对象具有相似状态的对象。 为此:

  • 实施可克隆
  • 覆盖clone()方法
  • 公开它在clone()中调用super.clone()然后复制任何可变对象的状态

任何人都可以举一个关于这个主题的简单例子!

2 个答案:

答案 0 :(得分:0)

克隆规则

Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object.
The general intent is that, for any object x, the expression:
1) x.clone() != x will be true
2) x.clone().getClass() == x.getClass() will be true, but these are not absolute requirements.
3) x.clone().equals(x) will be true, this is not an absolute requirement.

Here is a example 要克隆的类Employee

public class Employee implements Cloneable{

    private int empoyeeId;
    private String employeeName;
    private Department department;

    public Employee(int id, String name, Department dept)
    {
    this.empoyeeId = id;
    this.employeeName = name;
    this.department = dept;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
    return super.clone();
    }
    //Accessor/mutators methods will go there
    }

public class Department
{
    private int id;
    private String name;

    public Department(int id, String name)
    {
        this.id = id;
        this.name = name;
    }
    //Accessor/mutators methods will go there
}

因此,如果我们需要克隆Employee类,那么我们需要做类似的事情。

public class TestCloning {

    public static void main(String[] args) throws CloneNotSupportedException
    {
        Department dept = new Department(1, "Human Resource");
        Employee original = new Employee(1, "Admin", dept);
        //Lets create a clone of original object
        Employee cloned = (Employee) original.clone();
        //Let verify using employee id, if cloning actually workded
        System.out.println(cloned.getEmpoyeeId());

        //Verify JDK's rules

        //Must be true and objects must have different memory addresses
        System.out.println(original != cloned);

        //As we are returning same class; so it should be true
        System.out.println(original.getClass() == cloned.getClass());

        //Default equals method checks for refernces so it should be false. If we want to make it true,
        //we need to override equals method in Employee class.
        System.out.println(original.equals(cloned));
    }
}

输出:

1
true
true
false

答案 1 :(得分:0)

克隆是一个希腊词,意思是“分支”,指的是可以从树枝上创建新植物的过程。在生物学中,它是关于复制DNA。

在java中,它实质上意味着能够创建一个与原始对象具有相似状态的对象。 clone()方法提供此功能。在java中,尽管克隆是“打算”生成同一对象的副本,但不能保证。克隆有很多ifs和buts。

默认情况下,java克隆是' field by field copy ',即因为Object类不知道将调用clone()方法的类的结构。因此,当JVM调用克隆时,请执行以下操作:

  1. 如果类只有原始数据类型成员,则将创建该对象的全新副本,并返回对新对象副本的引用
  2. 如果类包含任何类类型的成员,则只复制对这些成员的对象引用,因此原始对象和克隆对象中的成员引用都引用同一对象
  3. 除了上述默认行为外,您始终可以覆盖此行为并指定自己的行为。

    根据java Doc(格式化和提取)。

    The general intent is that, for any object x, the expression:
    1) x.clone() != x will be true   ---- means that cloned object will have separate memory address assignment
    2) x.clone().getClass() == x.getClass() will be true, but these are not absolute requirements. ---- means original and cloned objects should have same class type, but it is not mandatory
    3) x.clone().equals(x) will be true, this is not an absolute requirement. ---- means original and cloned objects should have be equal using equals() method, but it is not mandatory
    

    浅拷贝通常克隆对象的方法,创建同一个类的新实例,并将所有字段复制到新实例并返回它。这只不过是浅色的副本。其中包含的对象不会被复制到克隆对象。示例 -

    public class Employee implements Cloneable{
    
    private String employeeName;
    private Department department;
    
    :
    :
    @Override
    protected Object clone() throws CloneNotSupportedException {
    return super.clone();
    }
    }
    

    深层复制深层复制会复制所有内容。但你必须自己实施它。

    public class Employee implements Cloneable{
    
    :
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Employee cloned = (Employee)super.clone();
        // get the Department object of “this” Employee and make copy of it and assign it to Employee object 
        cloned.setDepartment((Department)cloned.getDepartment().clone());
        return cloned;
    }}
    }
    

    指出要记住

    1. 当你不知道是否可以调用一个的clone()方法时 因为你不确定是否在那里实现了特定的类 在类中,您可以检查该类是否是实例 " Cloneable的"界面如下。

      if(obj1 instanceof Cloneable){     obj2 = obj1.clone(); }

    2. 由于Cloneabe接口是标记接口(没有任何方法 在它),你永远不能将对象强制转换为Cloneable并调用clone() 方法。检查下面。

      //不要这样做。 Cloneabe没有任何方法 obj2 =(Cloneable)obj1.clone();

    3. 没有为要克隆的对象调用构造函数。所以,你必须这样做 确保所有成员都已正确设置。

    4. 如果该类有最终字段,则不能在中给出这些值 克隆方法。

    5. 如果你的班级是单身,你必须照顾克隆

      public Object clone()抛出CloneNotSupportedException {     抛出新的CloneNotSupportedException(); }