复制对象字段

时间:2013-09-24 18:18:06

标签: java

当我需要有两个独立变量时,复制类的最佳方法是什么? 我有简单的课程:

public class MyClass 
{
boolean a = false;
String b= "not empty";
}

我需要制作一些方法,如:

assign(MyClass data )
{
a= data.a;
b= data.b;
}

是否有任何自动方法可以在java中复制(复制)对象?

3 个答案:

答案 0 :(得分:3)

  

我需要制作一些方法,如:

非常接近。你应该把它变成一个构造函数,而不是使它成为方法。这样的构造函数称为copy constructor,您可以像这样创建它们:

MyClass(MyClass data) {  
    a = data.a;
    b = data.b;
}

然后要创建实例的副本,您可以使用如下构造函数:

MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass(obj1);

复制构造函数可能很乏味

当您的类具有可变字段时,使用复制构造函数创建深层复制可能很繁琐。在这种情况下,像这样的赋值只会创建引用的副本,而不是对象本身。您还必须创建这些字段的副本(如果需要深层复制)。这可以递归。

创建深层副本的更好方法是序列化,然后反序列化您的对象。

为什么不使用clone()?

在对象类中添加clone()方法是一个很大的错误,IMO。你应该避免使用它来克隆对象。

  • 首先,要使用该方法,您必须实现Cloneable接口,这实际上并不具有clone()方法。事实上,它只是一个标记界面。
  • Object#clone()方法的返回类型为Object。因此,这意味着您实际上可以返回完全不相关的类的实例,从而在运行时将代码引导到潜在的ClassCastException

另见:

答案 1 :(得分:1)

您可以使用复制构造函数手动执行深度克隆,或者您可以使用可用于此目的的实用程序,例如:https://code.google.com/p/cloning/

如果你的类有很多非原始成员变量,深度克隆的复杂性会增加,我建议你使用那个实用程序。

答案 2 :(得分:0)

这两种方法,首先使用Cloneable接口(不是首选),另一种是在类中创建一个方法,返回具有当前状态的新实例

public class MyObject implements Cloneable {

    private int num = 0;

    // a method to show how to clone an object
    private void copyObject() throws CloneNotSupportedException {

        MyObject a = new MyObject();
        a.num = 10;

        MyObject b = (MyObject)a.clone();
        System.out.println(b.num);
        // result : 10
        // values are copied to the new object

        b.num = 20;
        System.out.println(a.num + " - " + b.num);
        // result : 10 - 20
        // 2 different objects, the new object didnt effect the original one
    }

    // a method to create a copy
    public MyObject copy() {
        MyObject copy = new MyObject();
        copy.num = this.num;
        // do the same to all your variables
        return copy;
    }

    // a method to show how to use the copy() method
    private void useCopy(){

        MyObject a = new MyObject();
        a.num = 100;

        MyObject b = a.copy();

        System.out.println(a.num+" - "+b.num); 
        //  result : 100 - 100
        //  value copied to the new Object

        a.num = 10;
        b.num = 20;
        System.out.println(a.num + " - " + b.num);
        //  result : 10 - 20
        //  although b was copied from a, but both are 2 different Objects
    }
}

还有另一种使用反射包复制值的方法,但毕竟,你确定你在设计方面走在正确的轨道上吗?

如果您能告诉我们您的想法,也许设计模式可能会有所帮助