Fix cloning of array types.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@960138 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Joerg Schaible 2010-07-03 00:30:46 +00:00
parent c90b815dab
commit 5e9fd18a88
2 changed files with 47 additions and 11 deletions

View File

@ -17,6 +17,7 @@
package org.apache.commons.lang3;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@ -326,18 +327,37 @@ public class ObjectUtils {
*/
public static <T> T clone(final T o) {
if (o instanceof Cloneable) {
try {
final Method clone = o.getClass().getMethod("clone", (Class[])null);
@SuppressWarnings("unchecked")
final T result = (T)clone.invoke(o, (Object[])null);
return result;
} catch (final NoSuchMethodException e) {
throw new CloneFailedException("Cloneable type has no clone method", e);
} catch (final IllegalAccessException e) {
throw new CloneFailedException("Cannot clone Cloneable type", e);
} catch (final InvocationTargetException e) {
throw new CloneFailedException("Exception cloning Cloneable type", e.getCause());
final Object result;
if (o.getClass().isArray()) {
final Class<?> componentType = o.getClass().getComponentType();
if (!componentType.isPrimitive()) {
result = ((Object[])o).clone();
} else {
int length = Array.getLength(o);
result = Array.newInstance(componentType, length);
while (length-- > 0) {
Array.set(result, length, Array.get(o, length));
}
}
} else {
try {
final Method clone = o.getClass().getMethod("clone");
result = clone.invoke(o);
} catch (final NoSuchMethodException e) {
throw new CloneFailedException("Cloneable type "
+ o.getClass().getName()
+ " has no clone method", e);
} catch (final IllegalAccessException e) {
throw new CloneFailedException("Cannot clone Cloneable type "
+ o.getClass().getName(), e);
} catch (final InvocationTargetException e) {
throw new CloneFailedException("Exception cloning Cloneable type "
+ o.getClass().getName(), e.getCause());
}
}
@SuppressWarnings("unchecked")
final T checked = (T)result;
return checked;
}
return null;

View File

@ -18,6 +18,7 @@ package org.apache.commons.lang3;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
@ -245,6 +246,21 @@ public class ObjectUtilsTest extends TestCase {
}
}
/**
* Tests {@link ObjectUtils#clone(Object)} with an object array.
*/
public void testCloneOfStringArray() {
assertTrue(Arrays.deepEquals(
new String[]{"string"}, ObjectUtils.clone(new String[]{"string"})));
}
/**
* Tests {@link ObjectUtils#clone(Object)} with an array of primitives.
*/
public void testCloneOfPrimitiveArray() {
assertTrue(Arrays.equals(new int[]{1}, ObjectUtils.clone(new int[]{1})));
}
/**
* Tests {@link ObjectUtils#cloneIfPossible(Object)} with a cloneable object.
*/