2013-04-03 53 views
0

我有以下。任何类型的复制对象

public static <T> T someMethod(T originalObject) { 

    T modifiedObject = /* copy of original object (HOW DO YOU DO THIS?) */ 

    /* Some logic that modifies the object. */ 
    ... 

    return modifiedObject; // without changing original Object 

} 

现在的问题是,如果你不知道什么类型的T可能是什么,那么如何创建一个T型拷贝?

REVISION - 更清楚我只是粘贴我的代码。

public class ObjectMerger { 

    public static <T> T merge(T original, T patch) throws IllegalArgumentException, IllegalAccessException { 

     Object mergedObject = original // TODO: implement a way to copy original 

     Field[] inheritedFields = patch.getClass().getFields(); 
     Field[] memberFields = patch.getClass().getDeclaredFields(); 
     Field[] allFields = (Field[]) ArrayUtils.addAll(inheritedFields, memberFields); 

     for (Field field : allFields) { 

      Boolean originalAccessibility = field.isAccessible(); 
      field.setAccessible(true); 

      Object fieldValue = field.get(patch); 

      if (fieldValue != null) { 

       Boolean fieldIsFinal = Modifier.isFinal(field.getModifiers()); 

       if (!fieldIsFinal) { 
        field.set(mergedObject, fieldValue); 
       } 

      } 

      field.setAccessible(originalAccessibility); 

     } 

     return mergedObject; 

    } 

} 

注:我试过说T延伸Cloneable,这是不行的。我相信实施Cloneable并不能确保克隆可见。

注意:注意重复!

对于那些标记为重复的请阅读问题。这是要求一种方法来复制未知类型的对象。无论如何,我已经明白这是不可能的。感谢大家的意见。

+0

你是不是想克隆对象? –

+0

你能否请进一步解释你为什么这样做?所以我们可以建议你一些正确的方法来做到这一点。 –

+0

我修改了我的问题。我希望这会更清楚一点。谢谢。 –

回答

2

如果你完全没有关于T的信息,你可以做的最好的就是测试它是否实现了Cloneable.clone()它。

if (originalObject implements Cloneable) { 
    T modifiedObject = originalObject.clone(); 
    // ... 
} else { 
    throw new IllegalArgumentException(); 
} 

你也限制T

public static <T extends Cloneable> T someMethod(T originalObject) { 
    T modifiedObject = originalObject.clone(); 
} 

在任何情况下,你怎么就修改你它是什么完全不知道对象计数?你的用例听起来有点奇怪。如果你描述你正在尝试做的事情(而不是如何你试图这样做)可能会更容易。

+0

我之前尝试过,没有运气。我不相信实现Cloneable确保克隆方法是可见的,编译器似乎同意。你会想到的。 我想要做的是通过检查字段合并使用反射的任何类型的两个对象。其实我已经创建了一个成功的方法,但我不想修改原始的。 –

+0

你是什么意思*合并两个对象*? –

+0

关于'Cloneable'和'.clone()'的可见性,你是对的。你可以尝试通过反射来调用它,但这看起来很不可靠。让我们看看你有什么要说的*合并两个对象*也许我们可以找到一个好的解决方案。 –

1

接下来的问题是,如何在创建T类型的副本,如果你不知道T可能是什么类型的?

如果你真的不知道T是什么,你完全不能复制。

首先,没有用于复制对象的通用API(任何给定类型可能支持或不支持clone())。

但是,主要原因是T可能根本不支持复制。例如,如果TFileInputStream?你如何期望复制一个实例?

此外,如果您不知道T是什么,您将如何实施/* Some logic that modifies the object. */

+0

那是对的我认为这个问题并不清楚 –

0

有两种选择:

  • 使用clone()Cloneable如已经在对方的回答
  • 建议如果你不想限制了Cloneable然后用deep/shallow clone library它使用反射。 (不推荐,但仍然是选项)。应注意对象支持复制。
1

如果你准备使用的XStream,这里是解决方案,

XStream xstream = new XStream(); 

return (T) xstream.fromXML(XSTREAM.toXML(originalObject)); 
1

正如标题所说任何类型的复制对象,然后我想只有你必须选择是使用反射API 。此外,即使你使用反射,你需要有一定的标准,取决于你所创造的东西的副本,喜欢什么属性,你想不想从源对象等复制