1

我有以下。

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 类型的副本?

修订版 - 为了更清楚,我将粘贴我的代码。

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 extends Cloneable ,这是不行的。我相信实施 Cloneable 并不能确保克隆是可见的。

注意:注意重复!

对于那些将其标记为重复的人,请阅读问题。这是在寻求一种方法来复制未知类型的对象。无论如何,据我所知,这是不可能的。感谢大家的意见。

4

5 回答 5

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();
}

无论如何,您如何指望修改您完全不知道它是什么的对象?你的用例听起来有点奇怪。如果您描述您正在尝试做的事情(而不是您尝试做的方式),可能会更容易提供帮助

于 2013-04-03T06:13:04.347 回答
1

T那么问题是,如果您不知道T可能是什么类型,如何创建类型的副本?

如果你真的不知道是什么T,你根本就无法复制。

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

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

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

于 2013-04-03T06:14:56.737 回答
1

如果您准备好使用 XStream,这里是解决方案,

XStream xstream = new XStream();

return (T) xstream.fromXML(XSTREAM.toXML(originalObject));
于 2013-04-03T06:23:25.030 回答
1

正如标题所说的 Copy Object of Any Type那么我认为您唯一的选择就是使用Reflection API。此外,即使您使用反射,您也需要根据您正在创建副本的内容制定一些标准,例如您想要从源对象复制哪些属性等。

于 2013-04-03T06:30:22.573 回答
0

有两种选择:

  • 使用clone()andCloneable已在其他答案中建议
  • 如果您不想限制为 Cloneable ,请使用使用反射的深/浅克隆库。不推荐,但仍然是一种选择)。应注意对象支持复制。
于 2013-04-03T06:16:10.323 回答