代码之家  ›  专栏  ›  技术社区  ›  finnw

用单个对象的克隆填充数组

  •  3
  • finnw  · 技术社区  · 14 年前

    用一个对象的克隆来填充Java数组是一种快速简便的方法吗?

    例如,之后:

    Rectangle[] rectangles = new Rectangle[N];
    fillWithClones(rectangles, new Rectangle(1, 2, 3, 4));
    

    这个 rectangles 数组将包含n个distinct Rectangle 实例,用相同的坐标初始化。

    我知道 Object.clone() 在Java中,但在这种情况下,我知道要复制的对象有非投掷,公开。 clone() 方法,但可以有公共副本构造函数,也可以没有。

    我猜有一个库方法可以做到这一点,但我不认为它在JDK、Commons集合或Guava中。

    4 回复  |  直到 14 年前
        1
  •  2
  •   C. K. Young    14 年前

    如果在编译时没有要使用的特定类型,则必须调用 clone 反射法。

    private static <T> T cloneByReflection(T object) {
        try {
            return (T) object.getClass().getMethod("clone").invoke(object);
        } catch (Exception e) {
            return null;    // or whatever you want to do
        }
    }
    
    public static <T> void fillWithClones(T[] array, T template) {
        for (int i = 0; i < array.length; ++i)
            array[i] = cloneByReflection(template);
    }
    
        2
  •  0
  •   Stephen C    14 年前

    @克里斯·杰斯特·杨的回答给了你一个做你想做的事情的方法。

    但我建议,执行此类操作的应用程序存在相当大的错误。

    • 为什么你的申请 需要 对随机事物的数组进行深度复制?如果你不知道事物的类型,你怎么知道复制是必要的?

    • 当数组包含不可克隆的对象时,应用程序应该做什么?你有例外吗?你放了一个 null 在数组中,是否需要稍后进行空检查?

    更好的设计是让您可能想要克隆的所有对象实现一个带有(public)clone方法方法的接口。这样您就可以有一个静态类型的解决方案(没有动态类型异常!)您可以避免调用 clone 反射的。

        3
  •  0
  •   Ash    14 年前

    如果是复制构造函数 可以 存在(如果它存在,您希望使用它),您可以这样做:

    (编辑:更新代码以使用数组而不是列表):

    private static <T> void fillWithClones( T[] array, T object )
    {
      try
      {
        @SuppressWarnings("unchecked")
        Class<T> clazz = (Class<T>)object.getClass();
        Constructor<T> c = clazz.getConstructor( object.getClass() );
    
        try
        {
          for ( int i = 0; i < array.length; i++ )
          {
            array[i] = (T)c.newInstance( object );
          }
        }
        catch ( Exception e )
        {
          // Handle exception or rethrow...
        }
      }
      catch ( NoSuchMethodException e )
      {
        // No copy constructor, try clone option...
      }
    }
    

    当然,可以整理一些异常处理。

        4
  •  0
  •   L. Cornelius Dol    14 年前

    对于矩形:

    public void fillWithClones(Rectangle[] arr, Rectangle src) {
        for(int xa=0,len=arr.length; xa<len; xa++) { arr[xa]=(Rectangle)src.clone(); }
        }