在java中将对象A初始化为另一个对象B

在java中将对象A初始化为另一个对象B,java,object,pointers,initialization,Java,Object,Pointers,Initialization,可能重复: 如何在java中初始化一个对象(比如A),并将其初始成员值设置为第二个对象(比如B)。初始化后,我想修改A的成员,而不修改B的成员。因此,在初始化A时,我只想复制B的数据。这是如何以良好的方式完成的???您可以实现并使用克隆 MyClass b = new MyClass(); MyClass a = b.clone(); 注意:有些类是不可克隆的,或者有不完整的实现。e、 g.只有当它们应该是深拷贝时才有浅拷贝 如果类是可序列化的,则可以在内存中对其进行序列化和反序列化。不太好

可能重复:


如何在java中初始化一个对象(比如A),并将其初始成员值设置为第二个对象(比如B)。初始化后,我想修改A的成员,而不修改B的成员。因此,在初始化A时,我只想复制B的数据。这是如何以良好的方式完成的???

您可以实现并使用克隆

MyClass b = new MyClass();
MyClass a = b.clone();
注意:有些类是不可克隆的,或者有不完整的实现。e、 g.只有当它们应该是深拷贝时才有浅拷贝

如果类是可序列化的,则可以在内存中对其进行序列化和反序列化。不太好,但它很管用


或者您可以创建自己的“复制”构造函数。

克隆是一种简单的复制选项。如果您想在需要更多控制的地方执行某项操作,请创建自己的方法,按照您的需要执行复制:

public MyType copy()
{
  MyType a = new MyType();
  // Initialize how you need to here, use the object this was called from if you'd like
  a.property = this.property;
  // etc.  
  return a;
}
这给了您更直接的控制,但需要更多的时间来编写代码。如果克隆符合你的目的,就坚持下去

编辑:我将根据你对这个答案的评论给出一个例子

假设我们有以下类型:

TypeA: has the following member variables
int number = 5; // Default value built in by constructor.
int letter = 'x'; // Value is 'a' when constructed but has been changed.
ArrayList<TypeB> list = {b1, b2, b3} // All are initialized.

TypeB: has the following member variables
double decimal = 5.32
TypeC someObject = ...

TypeC: has some stuff, but we are going to ignore it.
TypeA:具有以下成员变量
整数=5;//构造函数内置的默认值。
int字母='x';//值在构造时为“a”,但已更改。
ArrayList={b1,b2,b3}//全部初始化。
TypeB:具有以下成员变量
双十进制=5.32
TypeC someObject=。。。
有一些东西,但我们将忽略它。
现在,当我们想要复制TypeA时,我们必须执行以下操作:

  • 直接复制数字和字符,因为它们是值类型
  • 复制对ArrayList的引用,其中包含对某些TypeB的引用
  • 幸运的是,这些都是简单的步骤

    int copyNumber = this.number;
    char copyChar = this.letter;
    ArrayList<TypeB> copyList = this.list;
    return new TypeA(copyNumber, copyChar, copyList);
    
    int copyNumber=this.number;
    char copyChar=this.letter;
    ArrayList copyList=此.list;
    返回新的TypeA(copyNumber、copyChar、copyList);
    
    现在假设一个特定的构造函数接受这三个参数,但希望您能理解

    如果只想获取值,而不是对ArrayList中所有TypeB的引用,这将变得很棘手。您必须循环遍历ArrayList并创建复制其所有值的新TypeB(double和TypeC对象作为引用或值…)


    简而言之,您想要的是一个更容易执行的拷贝。简单赋值运算符使用基元类型复制值,并使用对象引用。

    一种可能的解决方案是在类上实现
    clone
    方法,并使用clone,如下所示:

    MyClass a = new MyClass();
    MyClass b = a;
    
    您会注意到,
    clone()
    实际上不是一个公共方法,因此您需要公开它。此外,您需要告诉Java您的对象是可克隆的(这是通过使您的类实现
    可克隆
    )。以下代码对此进行了说明:

    public class MyClass implements Cloneable {
    
        @Override
        protected MyClass clone() throws CloneNotSupportedException {
            return (MyClass)super.clone();
        }
    
    }
    

    这完全取决于成员的类型。我举个例子:

    class A
    {
        public float value;
        public int[] anArray;
    
        public A(B b)
        {
            //primitive may be assigned directly.
            this.value = b.value;
    
            // other types different approaches:
    
            //copy the contents of the array
            this.anArray = new int[b.anArray.length];
            System.arraycopy(b.anArray, 0, this.anArray, 0, b.anArray.length);
        }
    }
    
    class B
    {
        float value;
        int[] anArray;
        public B(int size)
        {
            this.value = 3f;
            this.anArray = new int[size];
            for (int i = size - 1; i >= 0; i--)
            {
                this.anArray[i] = i * 10;
            }
        }
    }
    
    B b = new B(5);
    A a = new A(b);
    

    请参阅…假设它实现了
    Cloneable
    ,并且此特定实现没有破坏
    clone
    。好的,但是如果我要复制的对象包含其他对象作为方法?@sjoerd999:您遇到了什么问题?我可能可以帮你。好的,我会试着解释:我有一个对象A,它有其他对象作为成员。并且还具有作为成员的数据结构(数组、列表等)。因此,复制构造函数会有点困难,因为据我所知,必须在基本数据类型级别复制所有内容。由于同样的原因,克隆也不会起作用。那怎么办呢?还是我现在把这个看似简单的问题弄得太难了?啊,所以问题变得有点棘手了。是否要将引用复制到这些其他对象?或者您只对这些对象表示的值感兴趣?我想复制基本数据类型、数组和列表的所有值。我想复制对对象A成员对象的引用。