创建对象的副本而不复制其属性引用

时间:2012-07-26 18:23:40

标签: java

解释:

public class SomeClass {
  int aNumber = 0;

  public void changeNumber(int number){
    aNumber = number;
  }

  public int getNumber(){
    return aNumber;
  }
} 


public class Testapp {

  public static void main(String[] args) {
    NewClass object1 = new NewClass();
    NewClass object2 = object1;

    object1.changeNumber(5);
    object2.changeNumber(2);
    System.out.println("object1: "+object1.getNumber());
    System.out.println("object2: "+object2.getNumber());
  }
}

这将输出: object1:2 object2:2

我如何输出: object1:5 object2:2

6 个答案:

答案 0 :(得分:5)

您有两种选择:

1)实现复制构造函数:

public SomeClass(SomeClass c) {
  this.aNumber = c.aNumber;
}

然后创建副本:

SomeClass object2 = new SomeClass(object1);

2)实现Cloneable接口并覆盖Object.clone():

public class SomeClass implements Cloneable {
  public SomeClass clone() {
    super.clone();
  }
}

然后创建副本:

SomeClass object2 = object1.clone();

注意:我省略了任何不会改变的代码。

答案 1 :(得分:1)

您没有复制该对象,您正在复制该引用。这意味着两个变量都引用同一个对象。

要创建对象,您必须使用new或调用使用它的方法。

由于您需要副本,因此您应该使对象实现Cloneable(如果需要,还可以实现clone())。

答案 2 :(得分:1)

现在如何设置它是object1object2指向内存中的相同位置。你必须这样做:

NewClass object1 = new NewClass();
NewClass object2 = new NewClass();
object1.changeNumber(5);
object2.changeNumber(2);
System.out.println("object1: "+object1.getNumber());
System.out.println("object2: "+object2.getNumber());

这样,object1object2是完全独立的对象。

答案 3 :(得分:0)

 public class Testapp {
public static void main(String[] args) {
 NewClass object1 = new NewClass();
 NewClass object2 = new NewClass();
  object1.changeNumber(5);
 object2.changeNumber(2);
 System.out.println("object1: "+object1.getNumber());
 System.out.println("object2: "+object2.getNumber());   } } 

你应该调用对象的新实例化,否则它们会引用内存中的相同位置。

答案 4 :(得分:0)

1。您已复制了引用而非对象。

2。由于对象引用变量都指向堆上的Same对象,因此两者都得到2作为答案..

3。使用new 运算符创建另一个对象并将其指定给object2参考。

还有一件事......它不是NewClass,而是代码中提到的SomeClass

SomeClass object1 = new SomeClass();
SomeClass object2 = new SomeClass();
object1.changeNumber(5);
object2.changeNumber(2);
System.out.println("object1: "+object1.getNumber());
System.out.println("object2: "+object2.getNumber());

答案 5 :(得分:0)

Object是类的一个实例,能够保存状态。使用new运算符创建对象 - 在您的案例中,对象是在new NewClass()

创建的

NewClass object1NewClass object2是对象引用变量 - 它们就像C / C ++中的指针一样。引用变量不保持状态 - 它们只指向对象状态所在的内存位置。

当您说NewClass object1 = new NewClass()时,new运算符会创建NewClass的实例并返回存储在object1引用变量中的内存位置。当您说NewClass object2 = object1时,object1中保存的内存位置详细信息将复制到object2 - 这里要注意的重要事项是没有创建新对象。只有一个对象,因此只有一个状态 - 这就是为什么当您使用object1object2引用变量更改状态时,前一个值将被覆盖。

如果你想要两个对象,那么你需要两次调用new - 这将为每个对象分配单独的内存位置。如果您有一个对象并且想要该对象的类似副本 - 将其状态复制到新的内存位置 - 那么您需要使用clone()类的Object方法。克隆创建一个新对象并将对象的当前状态复制到新对象 - 因此,如果您调用NewClass object2 = object1.clone()将创建新对象并将object1的状态复制到该对象,则将引用返回到object2 - 此处{ {1}}也称为本地副本。您需要遵循Java规范进行克隆 - 您需要实现object2接口以支持克隆对象 - 请参阅此链接以http://en.wikipedia.org/wiki/Clone_(Java_method开头)