package c12;
import java.util.*; class Int { 
   private int i; 
   public Int(int ii) { i = ii; } 
   public void increment() { i++; } 
   public String toString() { 
       return Integer.toString(i); 
   } 
} public class Cloning { 
   public static void main(String[] args) { 
       Vector v = new Vector(); 
       for(int i = 0; i < 10; i++ ) 
          v.addElement(new Int(i)); 
       System.out.println("v: " + v); 
       Vector v2 = (Vector)v.clone(); 
      //Increment all v2's elements: 
      for(Enumeration e = v2.elements(); 
            e.hasMoreElements(); ) 
          ((Int)e.nextElement()).increment(); 
        //See if it changed v's elements: 
       System.out.println("v2:"+v2);
       System.out.println("v:"+v);
      if (v2!=v)
       System.out.println("This is different");
      // System.out.println("v: " + v); 
   } 
}输出结果是这样的:
v: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
v2:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
v:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
This is different
明明是相同的,而且我看过内存的地址也是相同的,为什么判断出来就是不相同的呢?

解决方案 »

  1.   

    clone()是把對象複製了一份吧,複製出來的對象地址應該跟原對象地址是不同的,比較內容的話應該用equals方法
      

  2.   

    首先,内存地址肯定不一样
    不然就不叫clone了
    != 判断的就是内存地址应该用equals方法比较
      

  3.   

    查了下APIclone
    protected Object clone()
                    throws CloneNotSupportedException创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。这样做的目的是,对于任何对象 x,表达式: 
    x.clone() != x为 true,表达式: 
    x.clone().getClass() == x.getClass()也为 true,但这些并非必须要满足的要求。一般情况下: 
    x.clone().equals(x)为 true,但这并非必须要满足的要求。 
    按照惯例,返回的对象应该通过调用 super.clone 获得。如果一个类及其所有的超类(Object 除外)都遵守此约定,则 x.clone().getClass() == x.getClass()。 
    按照惯例,此方法返回的对象应该独立于该对象(正被复制的对象)。要获得此独立性,在 super.clone 返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要复制包含正在被复制对象的内部“深层结构”的所有可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含基本字段或对不变对象的引用,那么通常不需要修改 super.clone 返回的对象中的字段。 Object 类的 clone 方法执行特定的复制操作。首先,如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。注意,所有的数组都被视为实现接口 Cloneable。否则,此方法会创建此对象的类的一个新实例,并像通过分配那样,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我复制。所以,此方法执行的是该对象的“浅表复制”,而不“深层复制”操作。 Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。 
    返回:
    此实例的一个副本。 
    抛出: 
    CloneNotSupportedException - 如果对象的类不支持 Cloneable 接口,则重写 clone 方法的子类也会抛出此异常,以指示无法复制某个实例。
    另请参见:
    Cloneable
      

  4.   


    Vector v = new Vector();
    Vector v2 = (Vector)v.clone(); 
    if (v2!=v)v2和v是不相同的,支持小绵羊的说法。
      

  5.   

    我用了equals比较下来,还是不相同,为什么V,V2输出是相同的。那内存地址不同,那么V ,V2指向是不是相同呢?
      

  6.   

    我拿你的代碼運行了一下,改成equals方法是相同的v2.equals(v)返回true
      

  7.   

    那V1 ,V2的指向是相同的吗?equals比较下来是相同的。
      

  8.   

    Vector的clone和equals方法clone
    public Object clone()返回向量的一个副本。副本中将包含一个对内部数据数组副本的引用,而非对此 Vector 对象的原始内部数据数组的引用。 覆盖:
    类 Object 中的 clone
    返回:
    向量的一个副本
    另请参见:
    Cloneable
    equals
    public boolean equals(Object o)比较指定对象与此向量的相等性。当且仅当指定的对象也是一个 List、两个 List 大小相同,并且其中所有对应的元素对都相等 时才返回 true。(如果 (e1==null ? e2==null : e1.equals(e2)),则两个元素 e1 和 e2 相等)。换句话说,如果两个 List 包含相同顺序的相同元素,则这两个 List 就定义为相等。 指定者:
    接口 Collection<E> 中的 equals
    指定者:
    接口 List<E> 中的 equals
    覆盖:
    类 AbstractList<E> 中的 equals
    参数:
    o - 要与此向量进行相等性比较的对象 
    返回:
    如果指定的 Object 与此向量相等,则返回 true
    另请参见:
    Object.hashCode(), Hashtable
      

  9.   

    你定義的Int是一個對象,對象數組中存的是對象的引用,所以修改v2的內容v也會跟著改變
      

  10.   


    int[] a = { 1 }; int[] b = a.clone();
    b[0] += 1; System.out.println(b[0] + " " + a[0]);
    基本數據類型就不會改變
      

  11.   


    你改变的不是V2的属性,而是V2中的元素的属性
    只对V2进行add、remove的操作,v是肯定不会跟着变的
    但是你别忘了,
    他们包含的元素对象在刚clone完的时候是完全一样的
    所以你对V2内部元素的属性变化,会影响到v中
      

  12.   

    clone()方法是浅克隆只赋值基本类型与 String 类型 其它类型只是把地址传过去而已
    实现深clone ()可以通过 重写 clone()方法自行实现