Author: niallp Date: Thu Jan 28 13:20:22 2010 New Revision: 904076 URL: http://svn.apache.org/viewvc?rev=904076&view=rev Log: Port LANG-567 to 2.x branch - ArrayUtils.addAll() does not handle mixed types very well
Modified: commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/ArrayUtils.java commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/ArrayUtilsAddTest.java Modified: commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/ArrayUtils.java URL: http://svn.apache.org/viewvc/commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/ArrayUtils.java?rev=904076&r1=904075&r2=904076&view=diff ============================================================================== --- commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/ArrayUtils.java (original) +++ commons/proper/lang/branches/LANG_2_X/src/main/java/org/apache/commons/lang/ArrayUtils.java Thu Jan 28 13:20:22 2010 @@ -2956,9 +2956,11 @@ * * @param array1 the first array whose elements are added to the new array, may be <code>null</code> * @param array2 the second array whose elements are added to the new array, may be <code>null</code> - * @return The new array, <code>null</code> if <code>null</code> array inputs. - * The type of the new array is the type of the first array. + * @return The new array, <code>null</code> if both arrays are <code>null</code>. + * The type of the new array is the type of the first array, + * unless the first array is null, in which case the type is the same as the second array. * @since 2.1 + * @throws IllegalArgumentException if the array types are incompatible */ public static Object[] addAll(Object[] array1, Object[] array2) { if (array1 == null) { @@ -2969,7 +2971,22 @@ Object[] joinedArray = (Object[]) Array.newInstance(array1.getClass().getComponentType(), array1.length + array2.length); System.arraycopy(array1, 0, joinedArray, 0, array1.length); - System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + try { + System.arraycopy(array2, 0, joinedArray, array1.length, array2.length); + } catch (ArrayStoreException ase) { + // Check if problem was due to incompatible types + /* + * We do this here, rather than before the copy because: + * - it would be a wasted check most of the time + * - safer, in case check turns out to be too strict + */ + final Class type1 = array1.getClass().getComponentType(); + final Class type2 = array2.getClass().getComponentType(); + if (!type1.isAssignableFrom(type2)){ + throw new IllegalArgumentException("Cannot store "+type2.getName()+" in an array of "+type1.getName()); + } + throw ase; // No, so rethrow original + } return joinedArray; } Modified: commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/ArrayUtilsAddTest.java URL: http://svn.apache.org/viewvc/commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/ArrayUtilsAddTest.java?rev=904076&r1=904075&r2=904076&view=diff ============================================================================== --- commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/ArrayUtilsAddTest.java (original) +++ commons/proper/lang/branches/LANG_2_X/src/test/java/org/apache/commons/lang/ArrayUtilsAddTest.java Thu Jan 28 13:20:22 2010 @@ -41,6 +41,20 @@ return suite; } + public void testJira567(){ + Number[] n; + // Valid array construction + n = (Number[])ArrayUtils.addAll(new Number[]{new Integer(1)}, new Long[]{new Long(2)}); + assertEquals(2,n.length); + assertEquals(Number.class,n.getClass().getComponentType()); + try { + // Invalid - can't store Long in Integer array + n = (Number[])ArrayUtils.addAll(new Integer[]{new Integer(1)}, new Long[]{new Long(2)}); + fail("Should have generated IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + } + } + public void testAddObjectArrayBoolean() { boolean[] newArray; newArray = ArrayUtils.add((boolean[])null, false);