Author: joehni Date: Sat Jul 3 00:30:46 2010 New Revision: 960138 URL: http://svn.apache.org/viewvc?rev=960138&view=rev Log: Fix cloning of array types.
Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/ObjectUtils.java commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/ObjectUtils.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/ObjectUtils.java?rev=960138&r1=960137&r2=960138&view=diff ============================================================================== --- commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/ObjectUtils.java (original) +++ commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/ObjectUtils.java Sat Jul 3 00:30:46 2010 @@ -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; Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java?rev=960138&r1=960137&r2=960138&view=diff ============================================================================== --- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java (original) +++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/ObjectUtilsTest.java Sat Jul 3 00:30:46 2010 @@ -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; @@ -246,6 +247,21 @@ public class ObjectUtilsTest extends Tes } /** + * 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. */ public void testPossibleCloneOfCloneable() {