1

I have the following.

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

}

The question is then, how to a create a copy of type T if you have no idea what type T could be?

REVISION - to be more clear I will just paste my code.

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;

    }

}

Note: I have tried saying T extends Cloneable and it's a no go. I believe that implementing Cloneable does not ensure clone is visible.

NOTE: NOTE A DUPLICATE!

For those marking this as a duplicate please read the question. This is asking for a way to duplicate an object of a unknown type. Anyways from what I have come to understand this is not possible. Thanks to everyone for your input.

Marc M.
  • 3,631
  • 4
  • 32
  • 53

5 Answers5

2

If you have absolutely no information on what T is, the best you can do is to test if it implements Cloneable and .clone() it.

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

You could also restrict T:

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

In any case, how do you count on modifying an object that you have absolutely no idea on what it is? Your use case sounds a bit strange. It might be easier to help if you describe what you are trying to do (and not how you are trying to do it).

Bruno Reis
  • 37,201
  • 11
  • 119
  • 156
  • I was trying that earlier and no luck. I do not believe that implementing Cloneable ensures the clone method is visible, and the compiler seems to agree. You would think though. What I am trying to do is merge two object of any type using reflection by examining fields. Actually I have created a method that does that successfully, but I would like not to modify the original. – Marc M. Apr 03 '13 at 06:36
  • What do you mean by *merge two objects*? – Bruno Reis Apr 03 '13 at 06:37
  • About `Cloneable` and `.clone()`'s visibility, you are right. You could try calling it through reflection, but this seems very unreliable. Let's see what you have to say about *merge two objects* and maybe we can find a good solution. – Bruno Reis Apr 03 '13 at 06:39
  • Basically you have the original object and a patch. They are both of the same type. When you merge them it scans the values of all the fields in patch. If it's not null then it overrides the value original has for that same field. It does this for all fields. Hence the “Patched or Merged Object”. Perhaps patch would be a better name. – Marc M. Apr 03 '13 at 06:57
  • 1
    If you really have absolutely no control on the objects that your method should handle, there's no way to achieve what you want. What if I pass an instance of `Thread`, or `Socket`, or `InputStream` to your method? You really should restrict the objects you are willing to deal with. – Bruno Reis Apr 03 '13 at 07:00
1

The question is then, how to a create a copy of type T if you have no idea what type T could be?

If you really have no idea what T is, you quite simply cannot make a copy.

Firstly, there's no universal API for copying objects (any given type may or may not support clone()).

However, the main reason is that T might not support copying at all. For example, what if T is FileInputStream? How do you expect to copy an instance of that?

Besides, how are you going to implement /* Some logic that modifies the object. */ if you have no idea what T is?

NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

If you are ready to use XStream, here is the solution,

XStream xstream = new XStream();

return (T) xstream.fromXML(XSTREAM.toXML(originalObject));
Adisesha
  • 5,200
  • 1
  • 32
  • 43
1

As title says Copy Object of Any Type then I think only option you have is to use Reflection API. Also even if you use reflection you need to have some criteria depending on what you are creating a copy, like what attributes you want want to copy from source object etc.

Sachin Gorade
  • 1,427
  • 12
  • 32
0

There are two options:

  • Use the clone() and Cloneable as already suggested in other answer
  • If you do not want to restrict to Cloneable then use deep/shallow clone library which uses reflection. (Not recommended but still an option). Care should be taken that the object supports copying.
Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120